Вернуть список инициализаторов вместо вектора в std::function

Редактировать: Это не дублируется связанного вопроса (который также принадлежит мне). Здесь все возвращаемые типы std::vector. Я не хочу возвращать initializer-list. Я хочу заполнить возвращенный std::vector на initializer-list напрямую

Возьмем эти четыре случая:

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}; 
};

Почему 4 неприемлемо, если 2 приемлемо? чем они отличаются? Причем, самое странное, что это допустимо:

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

Что не так с std::function и initializer-list?


person Humam Helfawi    schedule 18.06.2016    source источник
comment
Перед тем, как я Мьёльнир это: Как связанный ответ не отвечает на это в ваших глазах?   -  person Baum mit Augen    schedule 18.06.2016
comment
Это отличается. Этот вопрос о возврате списка инициализаторов. здесь возвращаемый тип во всех случаях является вектором.   -  person Humam Helfawi    schedule 18.06.2016
comment
Тип возвращаемого значения не имеет значения. Дело в том, что вы не можете вывести тип автоматически, поэтому вам нужно указать его вручную.   -  person nwp    schedule 18.06.2016
comment
@nwp Разве это не считается указанием вручную? std::function‹std::vector‹int›()›   -  person Humam Helfawi    schedule 18.06.2016
comment
auto bar=[]()->std::vector<int>{ имеет значение, потому что вы явно указываете, что должна вернуть лямбда. std::function<std::vector<int>()> foo=[](){ не считается, потому что вы сначала выводите возвращаемый тип лямбды, а затем присваиваете его. C++ не принимает во внимание, что вы можете назначить лямбда при выборе типа, он видит return {1}, который является std::initializer_list<int> (я думаю).   -  person nwp    schedule 18.06.2016
comment
Ах! Теперь я понял .. Пожалуйста, вы можете сделать это как ответ .. спасибо   -  person Humam Helfawi    schedule 18.06.2016
comment
Я думаю, теперь вы можете позволить @BaummitAugen закрыть это как обман.   -  person nwp    schedule 18.06.2016
comment
@nwp Но на самом деле этот вопрос расширяет концепцию. и ответ там не содержит вашего примечания.   -  person Humam Helfawi    schedule 18.06.2016


Ответы (3)


auto bar=[]()->std::vector<int>{ указывает тип возвращаемого значения лямбды bar как std::vector<int>.

std::function<std::vector<int>()> foo=[](){ не определяет возвращаемый тип foo, потому что вы сначала выводите возвращаемый тип лямбды, а затем назначаете его.

C++ не принимает во внимание то, чему вы можете присвоить лямбду при выборе типа, он видит возвращаемое значение {1}, которое является std::initializer_list<int>, что несовместимо с std::function<std::vector<int>>.

person nwp    schedule 18.06.2016

Тип возвращаемого значения лямбды в (4) — auto, а не std::vector, как в (2) и как в вашем последнем примере, где вы все еще используете лямбду, но принудительно возвращаете тип.

Вычитание auto из return {1} приводит к std::initializer_list<int>(), что отличается от std::vector<int>(), ожидаемого std::function.

person Emilio Garavaglia    schedule 18.06.2016
comment
Вычет auto из возвращаемого значения {1} приводит к std::initializer_list‹int›(). Тот факт, что a в auto a={1}; становится списком инициализаторов, не означает, что []{return {1};} выводит initializer_list как возвращаемый тип. - person Piotr Skotnicki; 18.06.2016

Этот вариант компилируется:

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

Это идентично вашему случаю 4, за исключением явного возвращаемого типа в лямбда-выражении. Это показывает, что тип объявления std::function<> не распространяется на синтаксический анализ лямбда-выражения; лямбда анализируется независимо от окружающего выражения.

Я не уверен, является ли это особенностью стандарта языка C++ или ограничениями реальных компиляторов (я тестировал с помощью g++ -std=c++11), поскольку я не слишком хорошо разбираюсь в языковых юристах.

person cmaster - reinstate monica    schedule 18.06.2016