从c ++ 11中的用户定义的文字返回一个std :: array

时间:2013-07-10 04:02:34

标签: c++ c++11

我刚安装了gcc-4.8.1,当我意识到我可以做-std = c ++ 1y并获得多线constexpr时非常兴奋。我很想知道,无论如何要做到这一点吗?

#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;
}

但是我觉得很可怕:

$ 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;

反正有没有让这件事发生?我不能从constexpr返回一个std :: string,似乎没有任何我可以用模板或decltype做的事情。无论如何从参数中得到一个常量表达式?

1 个答案:

答案 0 :(得分:7)

您需要模板文字运算符。函数参数永远不是有效的常量表达式即使正常使用有意义,您的操作员仍然必须支持显式调用

形式
operator "" _a1 ( "hello", 5 );

对于整数和浮动用户定义的文字,有一个模板化表单可以返回array

template< char ... c >
constexpr std::array< char, sizeof ... (c) >
operator "" _a1 () {
    return { c ... };
}

字符串文字不支持(但?),可能是因为多字节编码问题。

所以,你在这种特殊的方法中运气不佳。

然而,您可以采取另一种方法,并将字符串作为数组。

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 ] ... }}; }

这需要一个支持模板index_helper来生成整数{ 0, 1, 2, ... size }的计数包。

另请注意,constexpr可能不适合您的应用程序。 constexpr函数不能包含一系列命令式语句。允许计算任何内容的唯一语句是return,或constexpr构造函数,成员初始化。

更新:Here's一个关于你可以做什么的演示,在C ++ 11中。