无法编译下面的代码:
#include <array>
template <class T, T state>
class stateless
{
public:
void f() { /* do something with m_val*/; }
private:
static inline constexpr T m_val = state;
};
struct A
{
int x;
int GetX() const { return x; }
};
template <class T, class ReturnType>
using FuncPtr = ReturnType(T::*)() const;
template <class T, class ReturnType>
class func_getter
{
public:
using object_type = T;
using value_type = ReturnType;
using MyFuncPtr = FuncPtr<T, ReturnType>;
constexpr func_getter(MyFuncPtr p) : m_p(p) {}
constexpr ReturnType operator() (const T& val) const
{
return (val.*m_p)();
}
private:
MyFuncPtr m_p;
};
int main()
{
{
using Array = std::array<int, 3>;
constexpr std::array<int, 3> a = { 1, 2, 3 };
stateless<Array, a> s;
}
{
constexpr A a = { 1 };
stateless<A, a> s;
}
// All the code above compiles, but the code below does not.
{
using Getter = func_getter<A, int>;
constexpr Getter g(&A::GetX);
stateless<Getter, g> s;
}
{
constexpr func_getter g(&A::GetX);
stateless<decltype(g), g> s;
}
return 0;
}
字符串
MSVC 2022错误:
error C2993: 'Getter': is not a valid type for non-type template parameter 'state'
型
3条答案
按热度按时间gijlo24d1#
问题是
Getter
(akafunc_getter<A, int>
)不是结构类型,所以它不能被用作非类型模板参数,按照temp.param:1.非类型模板参数应具有以下类型之一(可能是cv限定的):
*结构类型(见下文),
1.结构类型为下列之一:
*所有基类和非静态数据成员都是公共的和不可变的,
(强调我的)
由于
Getter
有一个私有 * 非静态 * 数据成员m_p
,它违反了上述规则,因此不是结构类型,不能用作非类型模板参数。hs1ihplo2#
完整的错误是:
字符串
重要的一点是
'func_getter<A, int>' is not a structural type
。结构类型不能有私有字段。whhtz7ly3#
g++的错误信息在这里更有帮助:
错误:“func_getter<A,int>”不是模板非类型参数的有效类型,因为它不是结构性的。
cppreference列出要求
非类型模板参数必须具有结构类型,该类型是以下类型之一(可选cv限定,限定符被忽略):
std::nullptr_t
;问题是
MyFuncPtr m_p;
是private
。See coliru的