c++ - 将 CRTP 与 static_assert 一起使用时出现编译器错误

标签 c++ gcc clang crtp static-assert

考虑以下代码:

template<typename Derived>
struct Base {
    static constexpr int x_base = Derived::x_derived;
    //static_assert(x_base > 1, "Oops");
};

struct Derived : public Base<Derived> {
    static  constexpr int x_derived = 5 ;
};

Base<Derived> obj;

这在 gcc 上编译得很好,但如果我取消注释 static_assert 行,它会提示

error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;

我尝试使用从 4.9 到 5.3 的不同版本的 gcc,我得到了同样的错误(你可以在 godbolt here 上尝试)。即使没有 static_assert,clang 也拒绝编译它,并提示说

error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;

哪个编译器是正确的(如果有的话)? 有修复代码的好方法吗?

最佳答案

访问嵌套名称需要类是完整的,但是 Derived 在这里还不完整:

template<typename Derived>
struct Base {
    static constexpr int x_base = Derived::x_derived;
                                  ^^^^^^^^^
};

所以代码格式错误。

有一些解决方法。首先,您可以单独将值作为模板参数传递:

template <typename Derived, int x_derived>
struct Base {
    static constexpr int x_base = x_derived;
};

struct Derived : public Base<Derived, 5> { };

其次,如果可能(例如,您不需要 x_derived 来声明任何成员),您可以将值移动到函数中以延迟其实例化:

template<typename Derived>
struct Base {
    static constexpr int x_base() {
        static_assert(Derived::x_derived > 1, "Oops");
        return Derived::x_derived;
    }

};

struct Derived : public Base<Derived> {
    static constexpr int x_derived = 5;
};

关于c++ - 将 CRTP 与 static_assert 一起使用时出现编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36869693/

相关文章:

c++ - tinyXml 如何创建xml

java - 寻找集合的幂集

python - 如何导入或安装预构建的 python 扩展模块 (C++)(即未通过 setuptools 编译的库)?

c++ - 带有 "noexcept"构造函数的程序被 gcc 接受,被 clang 拒绝

c - 如何在 gcc 中为复数启用 SSE3 addsubps 自动矢量化?

c - 为什么具有空参数列表的函数原型(prototype)与具有 char 参数的函数原型(prototype)冲突?

xcode - 如何获得Xcode “clang”编译时错误的调用?

c++ - 在导入 Foundation 的 objective-c 文件上运行 Clang-query

c - 针对没有源代码的 .so 文件的 GCC 链接

ios - 为 iOS 7 编译 x264