Reputation: 20264
Edit: It is not duplicated of the linked question (which is mine also). Here all the return types are
std::vector
. I do not want to return aninitializer-list
. I want to fill the returnedstd::vector
byinitializer-list
directly
Let us take those four cases:
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};
};
Why 4 is not acceptable since 2 is acceptable? what is the different between them? Moreover, the most strange thing that this is acceptable:
//Acceptable
auto bar=[]()->std::vector<int>{
return {1};
};
What is wrong with std::function
and initializer-list
?
Upvotes: 6
Views: 2618
Reputation: 40625
This variation compiles:
std::function<std::vector<int>()> foo=[]()->std::vector<int>{
return {1};
};
This is identical to your case 4, except for the explicit return type in the lambda expression. This shows that the type of the std::function<>
declaration does not propagate into the parsing of the lambda expression; the lambda is parsed independently of the surrounding expression.
I'm not sure whether this is a feature of the C++ language standard or of the limitations of real-world compilers (I tested with g++ -std=c++11
), since I'm not too much of a language lawyer.
Upvotes: 1
Reputation: 9991
auto bar=[]()->std::vector<int>{
specifies the return type of the lambda bar
to be std::vector<int>
.
std::function<std::vector<int>()> foo=[](){
does not specify the return type of foo
, because you first deduce the return type of the lambda, then assign it.
C++ does not take into account what you may assign the lambda to when deciding on a type, it sees return {1}, which is an std::initializer_list<int>
, which is incompatible with a std::function<std::vector<int>>
.
Upvotes: 4
Reputation: 20730
The return type of the lambda in (4) is auto
, and not std::vector
as in (2) and as in your last sample, where you are still using a lambda, but forced the return type.
The deduction of auto
in return {1}
leads to std::initializer_list<int>()
, that's different from std::vector<int>()
the std::function
expects.
Upvotes: 1