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;
};

它抱怨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;
}

在这里观看直播

问题就在这里:

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

在实例化 CRTP<A> 时,A 还不是一个完整的类,因此您实际上无法访问它的静态成员。

一种解决方法是将num作为单独的模板参数传入:

template <typename Derived, int N>
struct CRTP {
    static constexpr int num = N;
};
struct A : CRTP<A, 5> {
};

相关内容

最新更新