Можно ли игнорировать функцию завершающего возвращаемого типа в c ++ 11 в пользу функции вывода типа возвращаемого значения в c ++ 14?

Когда я пропускаю возвращаемый тип выражения

Следующий код в C ++ 11:

auto function(X x, Y y) -> decltype(x + y)
{
return x + y;
}

Равен следующему коду в C ++ 14:

decltype(auto) function(X x, Y y)
{
return x + y;
}

Но дополнительно можно вывести тип возврата без decltype правила в C ++ 14:

auto function()
{
return 0;
}

Когда я знаю, что именно возвращаемый тип

Следующий код в C ++ 11:

auto function() -> int
{
return 0;
}

Равен следующему коду в C ++ 03:

int function()
{
return 0;
}

Странный пример, который никогда не должен случиться

Следующий код в C ++ 11:

auto function(X x, Y y) -> decltype(x * y)
{
return x; // Yeah! return x with the type of x * y expression!
}

Равен следующему коду в C ++ 14:

decltype(auto) function(X x, Y y)
{
return static_cast<decltype(x * y)>(x);
}

Пожалуйста, исправьте меня, если приведенный выше код неверен и не работает должным образом.

РЕДАКТИРОВАТЬ, Согласно комментарию (Якк): Они на самом деле не равны, первый (C ++ 11 пример) является неявным приведением, в то время как второй ( static_cast из C ++ 14 пример) является явным приведением.

Заключение

Как видите, я могу делать все без использования синтаксис альтернативной функции особенность C ++ 11. Я прав? Могу ли я полностью забыть об этом без каких-либо технических проблем?

Как правило, можно избежать следующего синтаксиса:

auto function() -> TYPE
{
return 0;
}

В пользу следующего синтаксиса:

TYPE function() // TYPE can be: auto, decltype(auto), or ...
{
return 0;
}

Я забыл любое использование конечный тип возврата особенность C ++ 11, что невозможно с вычет типа возврата функции особенность C ++ 14?

12

Решение

Существует три важных различия между функцией, использующей автоматическое возвращение типа возврата, и функцией с явным типом возврата (даже если она вычисляется):

  1. Вы не можете выполнить SFINAE для вычислимости возвращаемого типа, если вы не укажете это явно: вместо этого вы получаете серьезную ошибку. Зачем? Поскольку SFINAE работает только с объявлением, не определение функций (SFINAE: (шаблон-аргумент) замена-сбой не является ошибкой).

    автоматический возврат типа вычет, нет СФИНАЕ
    SFINAE, но нет автоматического возврата типа возврата

    #include <iostream>
    int doit(int x, ...) { return x; }
    template<class X, class Y> auto doit(X x, Y y)
    #ifdef TRAILING_RETURN_TYPE
    -> decltype(doit(x) + doit(y))
    #endif
    { return doit(x) + doit(y); }
    int main() {
    std::cout << doit(1, nullptr) << std::endl;
    }
    
  2. На данный момент вы не можете заранее объявить функцию с ее фактическим типом возврата, если в определении используется автоматический возврат типа возврата, и при этом она не может быть виртуальной. (Явное правило)

    7.1.6.4 авто спецификатор [dcl.spec.auto]

    13 Повторные объявления или специализации функции или шаблона функции с объявленным типом возврата, который использует тип заполнителя, должен также использовать этот заполнитель, а не выводимый тип.
    14 Функция, объявленная с типом возврата, который использует тип заполнителя, не должна быть виртуальной (10.3).

  3. Только функции с автоматическим вычетом возвращаемого типа могут возвращать лямбду, так как нет другого способа получить ее тип.

    auto foo() { return [] {}; }
    

Ссылка на предложение, которое было включено в проект для C ++ 1y:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html

15

Другие решения


По вопросам рекламы [email protected]