c++ - 无法声明静态 constexpr char []

标签 c++ arrays c++11 static constexpr

我已经阅读了与此问题相关的所有答案,但老实说,我不确定我是否完全理解该解决方案。我正在使用 C++11。

假设我真的很想声明类似 static constexpr char value[] = "foo" 的东西.

如果我使用 NetBeans/TDM_MINGW,我会收到一个错误,我认为这是一个链接错误,报告未定义对“variable_name”的引用

在 MS VS 2015 中尝试相同的代码,我得到“表达式未计算为常量”

一个简单的static constexpr char *解决了问题,但我失去了使用像 sizeof 这样的表达式的能力.

简单直接的问题(如果可能直接回答):

  1. 有没有办法声明一个 static constexpr char [] 里面struct/class
  2. 如果 1) 为假,是否有最干净的解决方案来解决这个问题? <强> static constexpr char * ????
  3. 还是老 static const char [] 仍然是这种情况下的最佳方法吗?
  4. 我已经测试了一个有效但远非“干净”的解决方案 static constexpr array<char,50> getConstExpr(){ return array<char,50> {"Hell"} } .它工作正常,但我必须声明 char std::array 的大小:(

最佳答案

1) Is there a way to declare a static constexpr char [] inside struct/class?

是的;很简单。

下面是一个完整的工作示例

struct bar
 { static constexpr char value[] = "foo"; };

constexpr char bar::value[];

int main ()
 {
   std::cout << bar::value << std::endl; // print foo
 }

我想你忘记了 bar::value[] 行。

2) If 1) is false is there a cleanest solution to overcome this static constexpr char * ????

不适用。

3) Or the old static const char [] is still the best approach for this case?

取决于你要解决的问题;但通常我建议避免使用 C 风格的数组并使用新的 C++11 std::array

4) I've tested a solution that works but far from being "clean" [...] It works fine but I have to declare the size of the char std::array :(

我建议你一个解决方案(不幸的是从 C++14 开始工作,但制作 C++11 版本并不太难)来检测传递的 "Hell" 的正确大小范围。

观察 std::make_index_sequencestd::index_sequence 将单个字符从 char[] 变量传递到std::array.

template <std::size_t Dim, std::size_t ... Is>
constexpr std::array<char, Dim> gceH (char const (&str)[Dim],
                                      std::index_sequence<Is...> const &)
 { return { { str[Is]... } }; }

template <std::size_t Dim>
constexpr std::array<char, Dim> getConstExpr (char const (&str)[Dim])
 { return gceH(str, std::make_index_sequence<Dim>{}); }

int main ()
 {
   constexpr auto f = getConstExpr("Hell");

   static_assert( 5U == f.size(), "!" );
 }

-- 编辑 --

按照 Swift 的建议(谢谢!),使用模板类型代替 char,将 getConstExpr() 转换为更灵活的函数。

所以getConstExpr()和辅助函数(gceH())可以写成如下

template <typename T, std::size_t Dim, std::size_t ... Is>
constexpr std::array<T, Dim> gceH (T const (&str)[Dim],
                                   std::index_sequence<Is...> const &)
 { return { { str[Is]... } }; }

template <typename T, std::size_t Dim>
constexpr std::array<T, Dim> getConstExpr (T const (&str)[Dim])
 { return gceH(str, std::make_index_sequence<Dim>{}); }

关于c++ - 无法声明静态 constexpr char [],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45503329/

相关文章:

java - 仅对一个数组执行计算时,如何防止两个数组相等?

c++ - IOFrameBufferShared 中的不同游标格式

C++ - 使用 const 引用来延长临时成员,好的还是 UB?

c++ - 创建对话树

javascript - 更改一个索引位置处的数组值也会更改其他位置处的值

python - 用numpy计算距离矩阵

c++ - 如何在不降级为基类的情况下制作*对象的 vector

c++ - std::find 包含指针的 vector

C++制作二维 bool 矩阵

c++ - 如何使父类不重复已执行的祖父方法