从非类型模板参数声明 constexpr 数组的可移植方法
Portable way to declare constexpr array from non-type template arguments
我使用这种方法一段时间来做一些编译时的c-string操作:
template<char... args> struct String {static const char data[sizeof...(args)+1];};
template<char... args> constexpr const char String<args...>::data[sizeof...(args)+1] = {args...,' '};
它适用于所有符合 c++11 的编译器,但是我最近发现 clang 不会将访问data
成员视为 constexpr 常量:
enum Foo {
Bar = String<'f','o','o'>::data[1]
// read of non-constexpr variable 'data' is not allowed in a constant expression (clang)
// works fine (gcc)
};
但是,如果我像这样重写我的结构:
template<char... args> struct String {static constexpr const char data[sizeof...(args)+1] = {args...,' '};};
它可以在gcc和clang上工作。
问题是,第二种方法仅适用于 c++17,我希望它至少与 c++14 兼容。有什么办法吗?
在这种情况下,找出哪个编译器是正确的以及为什么也会很好。我已经搜索了规范,但没有找到第一种方法不应该是constexpr的任何理由。
问题是static const char
不是constexpr
!在这种情况下,叮当似乎就在这里!
如果你这样写:
template<char... args> struct String {
static constexpr char data[sizeof...(args)+1]={args...,' '};
};
enum Foo {
Bar = String<'f','o','o'>::data[1]
};
int main()
{
std::cout << Foo::Bar << std::endl;
}
它在 C++11 中适用于 clang 和 gcc。
顺便说一句:这让我想知道为什么两个编译器都没有抱怨在这种情况下data[]
的重复定义。
由于您直接初始化数组,因此无需再给出显式大小。因此,您可以简化为:
template<char... args> struct String {static constexpr char data[]{args...,' '};};
编辑:当我得到你的评论时,我也尝试了较旧的编译器版本并遇到了同样的麻烦。但是使用 gcc 7.1 我可以编译该版本:
template<char... args> struct String {static constexpr char data[sizeof...(args)+1]={args...,' '};};
template<char... args> constexpr char String<args...>::data[sizeof...(args)+1];
希望对您有所帮助!
据我所知,constexpr
成员的直接初始化也可以在 C++11 中工作
template<char... args>
struct String {
static constexpr const char data[sizeof...(args)+1] {args...,' '};
};
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何将临时 C 数组传递到 constexpr 容器中
- 任意大小的 constexpr 数组是否可以用作 switch 语句中的案例?
- C++:初始化 constexpr 构造函数中的成员数组
- C++访问静态 constexpr 数组
- 在 constexpr 构造函数中初始化数组是否合法?
- 从非类型模板参数声明 constexpr 数组的可移植方法
- 编译时生成应在构造函数中创建的非 constexpr 对象数组
- C++编译时使用 constexpr 字符数组指针分配静态数组?
- 我可以使用 constexpr 函数声明一个静态数组吗?
- 将constexpr字节数组与缓冲区的一部分(指向数据的指针)进行比较
- 正在初始化函数指针的constexpr数组
- constexpr数组初始化
- 类本身内部的类对象的静态constexpr数组
- const(但不是constexpr)用作内置数组大小
- 使用模板函数初始化 constexpr 数组
- 用另一个 constexpr 数组对成员数组进行大括号初始化
- C++ constexpr:在编译时计算标准数组
- 如何将constexpr数组传递到函数中
- 将`constexpr`与数组初始化