我已经阅读了与此问题相关的所有答案,但老实说,我不确定我是否完全理解该解决方案。我正在使用C ++ 11。
让我们说我真的想宣布像static constexpr char value[] = "foo"
这样的东西。
如果我使用NetBeans / TDM_MINGW,我会收到一个错误,我认为这是一个链接错误报告对“variable_name”的未定义引用。
在MS VS 2015中尝试相同的代码我得到“表达式没有评估为常量”。
一个简单的static constexpr char *
解决了这个问题,但我无法使用像sizeof
这样的表达式。
简单直接的问题(如果可能的话,直截了当的问题):
static constexpr char []
/ struct
内声明 class
?static constexpr char *
???? static const char []
仍是这种情况的最佳方法?static constexpr array<char,50> getConstExpr(){
return array<char,50> {"Hell"}
}
。它工作正常,但我必须声明char std::array
的大小:(答案 0 :(得分:3)
1) Is there a way to declare a
static constexpr char []
insidestruct
/class
?
Yes; it's simple.
The following is a full working example
struct bar
{ static constexpr char value[] = "foo"; };
constexpr char bar::value[];
int main ()
{
std::cout << bar::value << std::endl; // print foo
}
I suppose You forgot the bar::value[]
row.
2) If 1) is false is there a cleanest solution to overcome this
static constexpr char *
????
Not applicable.
3) Or the old
static const char []
is still the best approach for this case?
Depend from the problem you have to solve; but usually I suggest to avoid C-style arrays and use the new 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
:(
I propose you a solution (unfortunately work starting from C++14, but isn't too difficult make a C++11 version) to detect the correct size from "Hell"
passed as parameter.
Observe the use of std::make_index_sequence
and std::index_sequence
to pass the single chars from the char[]
variable to the 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(), "!" );
}
-- EDIT --
As suggested by Swift (thanks!) using a template type, instead char
, transform getConstExpr()
in a more flexible function.
So getConstExpr()
and the helper function (gceH()
) can be written as follows
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>{}); }
答案 1 :(得分:0)
如果你想避免C风格的数组,还有一个使用std :: string_view的C ++ 17解决方案......这要简单得多。 ;)
以下是perm-link以下代码。
#include <iostream>
#include <string_view>
int main ()
{
constexpr std::string_view foo ( "Hell" );
static_assert ( 4U == foo.size (), "!" );
std::cout << "Done";
return EXIT_SUCCESS;
}
答案 2 :(得分:0)
从C ++ 17开始,你不需要做任何特别的事情,因为static constexpr
成员变量是隐含的inline
。
以下工作:
#include <iostream>
struct S
{
static constexpr char value[] = "Meow!\n";
};
int main()
{
std::cout << S::value;
}