2016-10-24 9 views
1

無名配列の初期化リストキャスト:私は成功したchar型の文字列の配列の初期化子リストのCのキャストを行うことができますが、それは、C++のキャスト(static_castを)で動作するように見えることはできません

int main() 
{ 
    char x[] = "test 123"; 

    // This works fine: 

    char **foo = (char *[]) { "a", x, "abc" }; 
    std::cout << "[0]: " << foo[0] << " [1]: " << foo[1] 
      << " [2]: " << foo[2] << std::endl; 

    // This will not compile ("expected primary-expression before '{' token"): 

    //char **bar = static_cast<char *[]>({ "a", x, "abc" }); 
    //std::cout << "[0]: " << bar[0] << " [1]: " << bar[1] 
    //   << " [2]: " << bar[2] << std::endl; 
} 

ここでC++キャストを使用できますか?もしそうなら、正しい構文は何ですか?もしそうでないなら、私はやってはならない何かを私に奪わせるCキャストですか?

最終的には、これは私がパラメータとしてchar配列ポインタを持つ関数を呼び出すことを要求しているため、呼び出し引数として匿名配列を使用したいと考えています。

私はGCC 4.4.6を使用しています。

+0

これはC99のものです。* "カッコで囲まれた型名とそれに続くイニシャライザの囲まれたリストで構成されるpostfix式は**複合リテラル**です。" *、C++のような括弧付きの初期化子ではありません –

+0

'' std :: array 'を受け入れるようにその関数のシグネチャを変更してください。 –

答えて

3

私は正常にchar型の文字列の配列

いいえ、あなたはできないため初期化子リストのCのキャストを行うことができます。あなたはイニシャライザリストやCキャストをまったく使用しませんでした。あなたが使用したのは複合語です。 C++には存在しないC言語の機能です。いくつかのコンパイラは、言語拡張としてC++でそれらをサポートしています。

このような混乱を避けるために非標準機能を使用するときは、少なくとも警告するコンパイラオプションを使用することを強くお勧めします。

が、それはあなたが初期化子リスト式をキャストすることはできません

をキャスト++ Cで動作するように見えることはできません。配列は暗黙のうちにほとんどのコンテキストでポインタに暗黙に崩壊するので、別のポインタ変数はほとんど必要ありませんが、名前付き配列を通常は初期化してからポインタを初期化する必要があります。

const char* arr[] = { "a", x, "abc" }; 
const char** foo = arr; 

私はこれを求めている理由は、私は、パラメータとしてchar配列のポインタを持つ関数を呼び出しています、と私は、呼び出しの引数として無名配列を使用したいということです。

関数を変更できる場合は、名前付き配列なしで呼び出しを許可する方法があります。 std::initializer_list、またはstd::arrayなどのイニシャライザリストから作成できるタイプを受け入れることができます。


PS。文字列リテラルからchar*への暗黙の変換は、C++では許可されていませんが、一部のコンパイラでは言語拡張として許可されています。 const char*をここに使用してください。

+0

このドキュメントでは、https://gcc.gnu.org/onlinedocs/を実行しました。 gcc/Compound-Literals.htmlこのケースでは 'x'はリテラルではありません(しかし、その値は複合リテラルにリテラルとしてコピーされている可能性があります)。また、その文書が実際にキャストされたものであるかどうかについては、この文書は少し不明であった。これは、括弧で括られた式をキャストとして参照していますが、結果はキャストとは異なります。あなたの答え(とPiotr's)がより明確になります。私が言及した機能は遺産であるため、私はそれを変更することができないかもしれません。 – user3065699

+0

@ user3065699分かりやすくするために、複合リテラルのコンポーネントはリテラルである必要はありません。リンクしたドキュメントには、フィールドにもリテラル以外の値が設定された例が示されています。 – user2079303

関連する問題