Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CRTP编译错误_C++_Templates_C++11_Constexpr_Crtp - Fatal编程技术网

C++ CRTP编译错误

C++ CRTP编译错误,c++,templates,c++11,constexpr,crtp,C++,Templates,C++11,Constexpr,Crtp,以下内容将使用GCC 5.2编译,但不使用Visual Studio 2015 template <typename Derived> struct CRTP { static constexpr int num = Derived::value + 1; }; struct A : CRTP<A> { static constexpr int value = 5; }; 模板 结构CRTP{ 静态constexpr int num=Derived::

以下内容将使用GCC 5.2编译,但不使用Visual Studio 2015

template <typename Derived>
struct CRTP {
    static constexpr int num = Derived::value + 1;
};

struct A : CRTP<A> {
    static constexpr int value = 5;
};
模板
结构CRTP{
静态constexpr int num=Derived::value+1;
};
结构A:CRTP{
静态constexpr int值=5;
};
它抱怨
A
没有名为
value
的成员。
如何修复代码,使其在两个编译器上编译?或者它完全是非法的?

试着把它变成一个constexpr函数。您现在的设置方式尝试访问不完整的类型。
由于模板成员函数仅在首次使用时初始化,因此类型
a
将由该点完全定义

#include <iostream>

template <typename Derived>
struct CRTP {
    static constexpr int num() { return  Derived::value + 1; }
};

struct A : CRTP<A> {
    static constexpr int value = 5;
};

int main()
{
    std::cout << A::num();
    return 0;
}
#包括
模板
结构CRTP{
静态constexpr int num(){return-Derived::value+1;}
};
结构A:CRTP

问题在于:

template <typename Derived>
struct CRTP {
    static constexpr int num = Derived::value + 1;
                               ↑↑↑↑↑↑↑↑↑
};

它也无法在clang上编译。这是非法语法吗,GCC只是侥幸逃脱了?我不确定,但它看起来应该是非法的,否则您可能会有
num=Derived::value
value=CRTP::num
,但在GCC上它会编译,而且在运行我的程序时,所有输出都是预期的,也就是说,没有未定义的行为。
Derived=A
不完整,因此我怀疑这是否有效
CRTP::num
的初始值设定项在实例化
CRTP
时为什么需要实例化?你能提供标准的参考吗?我发现的是
[temp.inst]p9
:“类模板的隐式实例化不会导致该类的任何静态数据成员被隐式实例化”。@HighCommander4与成员的定义有关-声明仍然必须被解析和有效,在OP的示例中,由于
派生
尚未完成,因此它不在OP的示例中。
template <typename Derived, int N>
struct CRTP {
    static constexpr int num = N;
};

struct A : CRTP<A, 5> {

};