6

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 でできることはないようです。パラメータから定数式を取得する方法はありますか?

4

1 に答える 1

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コンストラクターの場合はメンバーの初期化です。

更新:これは、C++11 でできることの小さなデモです

于 2013-07-10T04:10:59.260 に答える