奇怪的重复模板模式 (CRTP),在 Clang 中使用静态 constexpr
Curiously recurring template pattern (CRTP) with static constexpr in Clang
考虑我下面的简单例子:
#include <iostream>
template <typename T>
class Base
{
public:
static constexpr int y = T::x;
};
class Derived : public Base<Derived>
{
public:
static constexpr int x = 5;
};
int main()
{
std::cout << Derived::y << std::endl;
}
在 g++ 中,这可以很好地编译并按预期打印5
。 但是,在 Clang 中,它无法编译并显示错误 no member named 'x' in 'Derived'
. 据我所知,这是正确的代码。 我正在做的事情有问题吗,如果没有,有没有办法在 Clang 中完成这项工作?
如注释中链接的那样,使用派生类的静态 constexpr 数据成员初始化基类的静态 constexpr 数据成员表明,此处的 clang 行为符合标准,最高可达 C++14。从 Clang 3.9 开始,您的代码使用 -std=c++1z
成功编译。一个简单的解决方法是使用 constexpr 函数而不是值:
#include <iostream>
template <typename T>
class Base
{
public:
static constexpr int y() {return T::x();}
};
class Derived : public Base<Derived>
{
public:
static constexpr int x() {return 5;}
};
int main()
{
std::cout << Derived::y() << std::endl;
}
这可能不是任何人想要的答案,但我通过添加第三个类解决了这个问题:
#include <iostream>
template <typename T>
class Base
{
public:
static constexpr int y = T::x;
};
class Data
{
public:
static constexpr int x = 5;
};
class Derived : public Base<Data>, public Data {};
int main()
{
std::cout << Derived::y << std::endl;
}
它可以按预期工作,但不幸的是,它并没有真正具有 CRTP 的好处!
相关文章:
- Clang 8 带有静态 constexpr 和数组的链接器错误 - 错误是什么以及如何解决它?
- 类无法访问自己的私有静态 constexpr 方法 - Clang bug?
- ConstexPR :GCC比Clang更努力地评估ConstexPR
- constexpr 使用 clang 编译 TensorFlow 时出错
- constexpr 函数的常量引用参数:gcc/msvc vs clang/icc
- 为什么 clang 并不总是为相同的静态 constexpr 产生常量值
- l值引用对象上的Constexpr成员函数:Clang和gcc不同意
- ADL 在 constexpr 函数中不起作用(仅限 clang)
- Clang, std::next, libstdc++ and constexpr-ness
- Clang声称通用lambda参数的constexpr成员不是constexpr
- enable_if is_same constexpr函数使MSVC失败(但在Clang,GCC中效果很好)
- Clang说is_same_v<int,double>的用法不是constexpr,不知道它怎么不是
- 海湾合作委员会和Clang在lambda的constexpr-ness上存在分歧?
- constexpr 唯一 ID,使用 clang 编译,但不使用 GCC 编译
- MSVC 和 clang for if constexpr 分支的不同行为
- constexpr(但不是真正的)构造函数在GCC中编译,而不是在Clang中编译
- 如果Constexpr - clang vs.GCC,则非constexpr变量
- Clang 在编译时不会计算非 constexpr 变量的 constexpr 函数的值
- gcc 和 clang 中 constexpr 静态成员变量的链接器错误
- 使用 constexpr 函数的结果作为模板参数(clang vs gcc)