Humam Helfawi
Humam Helfawi

Reputation: 20264

Return initializer list instead of vector in std::function

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 an initializer-list. I want to fill the returned std::vector by initializer-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

Answers (3)

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

nwp
nwp

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

Emilio Garavaglia
Emilio Garavaglia

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

Related Questions