2013-06-12 23 views
5

私はC++ 11を勉強していて、均一なイニシャライザを見つけました。ここで最も混乱している解析の混乱

#include<iostream> 


class Timer 
{ 
public: 
    Timer() {} 
}; 

int main() 
{ 

    auto dv = Timer(); // What is Timer() ? And what type is dv? 

    int time_keeper(Timer()); // This is a function right? And why isn't the argument " Timer (*)()" ? 



    return 0; 
} 
+0

2番目の行がMVPを呼び出すAFAIK、最初の行はMVPを呼び出さない。 –

+0

私はそれを知っていますが、コードに含まれる型と混同しています –

答えて

9

私は「最も厄介な解析」あいまいさを示す必要があり、次のコードを理解していない

auto dv = Timer(); 

あなたはdvと呼ばれるタイプTimerの対象であることを持っています(=符号の右側の式)からコピー初期化されています。

autoを使用して変数を宣言する場合、その変数の型は初期化する式の型と同じです。ここではcv修飾子と参照は考慮しません。

dvを初期化する式のタイプはTimerであり、dvのタイプはTimerです。ここで

int time_keeper(Timer()); 

あなたはintを返し、その入力としてTimerを返し、引数をとらない関数へのポインタかかりtime_keeperという関数を宣言します。

なぜ、引数がTimer (*)()ではないのですか?

関数は引数として渡されたときにポインタに崩壊するので、タイプtime_keeperは実際にはint(Timer(*)())です。

自分を納得させるには、この小さなプログラムをコンパイルしてみてください:

ここ
#include <type_traits> 

struct Timer { }; 
int main() 
{ 
    int time_keeper(Timer()); 
    static_assert(
     std::is_same< 
      decltype(time_keeper), 
      int(Timer(*)()) 
     >::value, 
     "This should not fire!"); 
} 

live exampleです。

+0

ありがとう、引数は "Timer(*)()"ではないでしょうか? "Timer()"も許容できる関数ポインタですか? –

+1

私は、 'functionName'と'&functionName'が同じものだと思います。 – Spook

+0

@DavidKernin:関数引数として使用すると、関数は自動的にポインタに崩壊するので、 'void(Timer())'と 'void(Timer(*)())'は同じ型です。 –

-4

ここではすべてが良いです。毎回タイマーのインスタンスを取得するだけです。

それがこのケースで

Timer name(); 

形式でなければならない関数の宣言であるために、あなたはその場合の正しい構文があること、何かをインスタンス化しません:

Timer name; 
+0

-1:いいえ、それは良くありません。 'time_keeper'は関数です。これは 'int'を返し、暗黙のうちに崩壊したポインタ型の引数をとり、引数を取る引数なしのタイマを返します。 – Angew