returning a std::array from a user defined literal in c++11
c++, c++11
Solution
You need a template literal operator. Function parameters are never valid constant expressions; even if normal usage makes sense your operator still has to support an explicit call of the form
operator "" _a1 ( "hello", 5 );
For integer and floating user-defined literals, there is a templated form that can return an `array`:
template< char ... c >
constexpr std::array< char, sizeof ... (c) >
operator "" _a1 () {
return { c ... };
}
This is not (yet?) supported for string literals, perhaps because of issues with multibyte encoding.
So, you're out of luck in this particular approach.
You can take another tack, though, and take the string as an array.
template< std::size_t size >
constexpr std::array< char, size >
string_to_array( char const (&str)[ size ] )
{ return string_to_array( str, make_index_helper< size >() ); }
template< std::size_t size, std::size_t ... index >
constexpr std::array< char, size >
string_to_array( char const (&str)[ size ],
index_helper< index ... > )
{ return {{ str[ index ] ... }}; }
This needs a support template `index_helper` to generate a counting pack of integers `{ 0, 1, 2, ... size }`.
Also note that `constexpr` may not work for the application you have in mind. A `constexpr` function cannot contain a sequence of imperative statements. The only statement allowed to compute anything is a `return`, or for a `constexpr` constructor, a member initialization.
Update: Here's a little demo of what you can do, in C++11.
Problem
I've just installed gcc-4.8.1 and was pretty excited when I realised I can do -std=c++1y and get multiline constexpr. I'm curious to know, is there anyway to make this work? ``` #include <array> constexpr auto operator "" _a1 (const char* text, const size_t size) -> std::array<char,size> { std::array<char,size>() blah; std::strncpy(blah.data(), test, size); // do some stuff to blah at compile time return blah; } int main() { auto blah = "hello world"_a2; } ``` But I get a big horrible: ``` $ g++ test.cpp -std=gnu++1y -Wall -Werror -Wextra -Weffc++ -pedantic test.cpp:3:100: error: use of parameter ‘size’ outside function body constexpr auto operator "" _a1 (const char* text, const size_t size) -> std::array<char,size> { ^ test.cpp:3:100: error: use of parameter ‘size’ outside function body test.cpp:3:100: error: use of parameter ‘size’ outside function body test.cpp:3:104: error: template argument 2 is invalid constexpr auto operator "" _a1 (const char* text, const size_t size) -> std::array<char,size> { ^ test.cpp: In function ‘int main()’: test.cpp:26:17: error: unable to find string literal operator ‘operator"" _a1’ auto blah = "hello world"_a1; ``` Is there anyway to make this happen? I can't return a std::string from a constexpr and there doesn't appear to be anything I can do with templates or decltype. Is there anyway to get a constant expression from a parameter?