c++ T不是非类型模板参数的有效类型

cnjp1d6j  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(111)

无法编译下面的代码:

#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'

gijlo24d

gijlo24d1#

问题Getter(aka func_getter<A, int>)不是结构类型,所以它不能被用作非类型模板参数,按照temp.param:

1.非类型模板参数应具有以下类型之一(可能是cv限定的):

*结构类型(见下文),

1.结构类型为下列之一

  • 具有以下属性的文字类类型:
    *所有基类和非静态数据成员都是公共的和不可变的,

(强调我的)
由于Getter有一个私有 * 非静态 * 数据成员m_p,它违反了上述规则,因此不是结构类型,不能用作非类型模板参数。

hs1ihplo

hs1ihplo2#

完整的错误是:

template <class T, T state>
                     ^
pp.cpp:65:9: note: while substituting prior template arguments into non-type template parameter 'state' [with T = func_getter<A, int>]
        stateless<Getter, g> s;
        ^~~~~~~~~~~~~~~~~~~~
pp.cpp:44:15: note: 'func_getter<A, int>' is not a structural type because it has a non-static data member that is not public
    MyFuncPtr m_p;

字符串
重要的一点是 'func_getter<A, int>' is not a structural type。结构类型不能有私有字段。

whhtz7ly

whhtz7ly3#

g++的错误信息在这里更有帮助:
错误:“func_getter<A,int>”不是模板非类型参数的有效类型,因为它不是结构性的。
cppreference列出要求
非类型模板参数必须具有结构类型,该类型是以下类型之一(可选cv限定,限定符被忽略):

  • 左值引用类型(对象或函数);
  • 整数型
  • 指针类型(指向对象或函数);
  • 指向成员类型的指针(指向成员对象或成员函数);
  • 枚举类型;
  • std::nullptr_t ;
  • 浮点类型;
  • 具有以下属性的文字类类型:
  • 所有基类和非静态数据成员都是公共的和不可变的,
  • 所有基类和非静态数据成员的类型都是结构类型或其(可能是多维的)数组。

问题是MyFuncPtr m_p;private
See coliru

相关问题