2011-08-17 13 views
12

C++でちょっと遊んでください。私が本当にやりたいことは、配列またはポインタ引数のために定義されたデフォルト値で関数を設定できることです。物事を単純にするために、単に配列を使ってみましょう。これと同じように:配列引数のデフォルト値

void experimentA(char a[3] = {'a', 'b', 'c'});

コンパイラ(GNU99とLLVM GCC 4.2)は、 "期待表現を" 文句を言います。それはかなり鈍いですが、割り当てようとしている '値'が静的に割り当てられているので、これが起こっていると私は同僚から言われましたが、変数(a[3])に割り当てようとしています。

しかし、私はこれを行うことができるよ以来、私は、そのような場合、完全にはわからない:

void experimentB(char a[3] = "abc");

をコンパイラは単に私にその文字列リテラル文字までを警告変換が推奨されていません* 。

この不一致を引き起こすために、「abc」と基本的に{'a'、 'b'、c}との違いはわかりません。どんな洞察も大変ありがとう!

+0

:たとえば、以下のタイプchar *型である形式のパラメータのデフォルトパラメータ値をシミュレートこれはサイズ4の配列に収まります。 –

+1

@Doug:文字列リテラルを使用してcharの配列を初期化する場合、ヌルターミネータのためのスペースは必要ありません。プログラマが明示的な長さを指定している場合、彼は自分が何をしているのかを知っているはずです。 –

答えて

6

あなたの同僚は間違っているか、誤解されている可能性があります。

最初のヒントは、CまたはC++の関数パラメータとして配列を持つことができないことです。理由は歴史的です。したがって、void experimentA(char a[3] ...)と書くと、コンパイラは自動的にポインタをvoid experimentA(char* a ...)に変換します。実際の質問はなぜ​​がaの適切なデフォルト値であり、{ 'a', 'b', 'c' }がそうでないかということです。理由は、コンパイラの説明によると、​​は式であり、{ 'a', 'b', 'c' }(初期化子)ではありません。 C++には、イニシャライザを使用できる場所とできない場所があります。パラメータのデフォルト値は、できない場所の1つに過ぎません。

+0

優れています。それは理にかなっている。あまりにも私は答えの一つだけを「答え」として選ぶことができません。 –

1

​​は、式であり、{'a', 'b', 'c'}はスタティックイニシャライザです。後は、変数宣言でのみ許可されます。私には分からない理由のために、デフォルト値での引数は静的な初期化子を許可しない別の文法規則を持っています。

スタティックイニシャライザがC++ 0xで許可されている場合、いくつかの重要な変更がありますが、問題のケースにどのように影響するかはわかりません。

4

文字列リテラル "abc"を使用すると、メモリのどこかにコンパイラによって割り当てられ、最初の文字へのポインタがデフォルト値として使用されます。したがって、コンパイラのコードは次のようになります:void experimentA(char a[3] = 0x12345678);

2番目のケースでは、配列リテラルはコンパイラによって文字列として割り当てられません(これは言語の不一致と思われます)。

2

​​は、の式です。 array of charの変数を初期化するために使用されるとき、他のすべての式とは異なり、特別な動作をします。

{'a','b','c'}は式ではなく、イニシャライザです。これは、変数定義でのみ構文上許されます。そこでは、シンタックスで式または非式の初期化子を使用できますが、初期化子をどこでも式として使用できるわけではありません。

+0

+1イニシャライザの有効な使用例を説明します。ありがとう、私が残していた些細な疑いをなくしました。 –

1

デフォルトのパラメータが有効である必要があります。

あなたが( "ABC")

Fを呼び出すことができ

決して

F({ 'A'、 'B'、 'C​​'})。

"abc"は実質的にメモリ内のアドレスであり、{'a'、 'b'、 'c'}は配列または構造体/クラスを初期化することを意味します。

0

これを行う簡単な方法の1つは、古い関数のオーバーロードによるものです。 "ABC" は本当に{ 'A'、 'B'、 'C​​'、 '\ 0'}である点に注意してください

static string to_string(time_point<system_clock> time) 
{ 
    return to_string(time, "%Y-%m-%d-%H-%M-%S"); 
} 

static string to_string(time_point<system_clock> time, const char* format) 
{ 
    time_t tt = system_clock::to_time_t(time); 

    char str[1024]; 
    if (std::strftime(str, sizeof(str), format, std::localtime(&tt))) 
     return string(str); 
    else return string(); 
} 
関連する問題