无法声明静态constexpr char []

Jac*_*nde 5 c++ arrays static constexpr c++11

我已经阅读了与此问题相关的所有答案,但老实说,我不确定我是否完全理解该解决方案.我正在使用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:(

max*_*x66 4

1)有没有办法声明一个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
 }
Run Code Online (Sandbox Code Playgroud)

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

2)如果1)为假,是否有最干净的解决方案来克服这个问题static constexpr char *???

不适用。

3)或者旧的方法static const char []仍然是这种情况下的最佳方法?

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

4)我已经测试了一个可行的解决方案,但远非“干净”[...]它工作正常,但我必须声明 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(), "!" );
 }
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

正如 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>{}); }
Run Code Online (Sandbox Code Playgroud)