2016-06-18 7 views
6

編集:これはリンクされた質問(これも私のものです)と重複しません。戻り値の型はすべてstd::vectorです。私は 返信したくないinitializer-listを返します。私はinitializer-listによって返さ std::vectorを埋めたい直接std :: functionのベクタの代わりにイニシャライザリストを返します。

は、私たちは、これらの4例を見てみましょう:

1)

//Acceptable 
std::vector<int> foo(){ 
    return std::vector<int>{1}; 
} 

2)

//Acceptable 
std::vector<int> foo(){ 
    return {1};  
} 

3)

//Acceptable 
std::function<std::vector<int>()> foo=[](){ 
    return std::vector<int>{1}; 
}; 

4)

//NOT Acceptable 
std::function<std::vector<int>()> foo=[](){ 
    return {1}; 
}; 

2が許容可能であるので、4が受け入れられないのはなぜ?彼らの間には何が違うのですか?また、これは許容可能であることが最も奇妙なことは:

//Acceptable 
auto bar=[]()->std::vector<int>{ 
    return {1}; 
}; 

std::functioninitializer-listの何が問題になっているのですか?

+3

[なぜ私はラムダからイニシャライザリストを返すことができません](http://stackoverflow.com/questions/35361408/whyi-i-can-not-return-initializer-list-from-lambda) –

+0

の可能な複製私はこれをMjölnir:リンクされた答えはあなたの目でこれにどのように答えていないのですか? –

+0

それは異なっています。 Initializerリストを返すことについての質問。すべての場合の戻り値の型はベクトルです。 –

答えて

4

auto bar=[]()->std::vector<int>{は、barの戻りタイプをstd::vector<int>と指定しています。

std::function<std::vector<int>()> foo=[](){は、最初にラムダの戻り値の型を推定してから割り当てますので、戻り値の型はfooではありません。

C++では、型を決定するときにラムダを割り当てることは考慮されていません。戻り値は{0}です。std::initializer_list<int>です。これはstd::function<std::vector<int>>と互換性がありません。

1

この変化は、コンパイルされます。

std::function<std::vector<int>()> foo=[]()->std::vector<int>{ 
    return {1}; 
}; 

これは、ラムダ式で明示的な戻り値の型を除いて、あなたのケース4と同じです。これは、std::function<>宣言の型がラムダ式の解析に伝播しないことを示しています。ラムダは周囲の式とは独立して解析されます。

これはC++言語標準の機能であるか、現実のコンパイラの制限(私はg++ -std=c++11でテストしました)の制限であるかどうかはわかりません。なぜなら私はあまり言語弁護士ではないからです。 (4)中のラムダの

1

戻り値の型はautoではなく、std::vector(2)のように、あなたはまだラムダを使用しますが、戻り値の型を余儀なくされ、あなたの最後のサンプル、のように。 return {1}

autoの控除はそれがstd::vector<int>()std::functionを期待異なるだ、std::initializer_list<int>()につながります。

+0

* "返品{1}での自動控除は、std :: initializer_list ()" *につながります。 'auto {= {1};}の' a 'がイニシャライザリストになるという事実は、 '[] {return {1};}'が返す型として 'initializer_list'を導くことを意味しません。 –

関連する問題