I've read all the answers related with this issue but honestly I'm not sure if I've fully understand the solution. I'm using C++11.
Lets say I really would like to declare something like static constexpr char value[] = "foo".
If I use NetBeans/TDM_MINGW I get an error which I suppose is a link error reporting undefined reference to "variable_name".
Trying the same code in MS VS 2015 I get "expression did not evaluate to a constant".
A simple static constexpr char * solves the problem but I lost the ability of using expressions like sizeof.
Simple and straightforward questions (if possible straightforward anwsers) :
static constexpr char [] inside struct/class?static constexpr char *????static const char [] is still the best approach for this case?static constexpr array<char,50> getConstExpr(){
return array<char,50> {"Hell"}
}. It works fine but I have to declare the size of the char std::array :(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>{}); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With