Почему decltype (auto) не работает должным образом? - PullRequest
0 голосов
/ 11 декабря 2018
#include <type_traits>
#include <utility>

int main()
{
    auto f1 = [](auto&& e) -> auto
    {
        return e;
    };

    auto f2 = [](auto&& e) -> auto&
    {
        return e;
    };

    auto f3 = [](auto&& e) -> auto&&
    {
        return e;
    };

    auto f4 = [](auto&& e) -> decltype(auto)
    {
        return e;
    };

    int n{};

    f1(std::move(n)); // ok
    f2(std::move(n)); // ok
    f3(std::move(n)); // ok
    f4(std::move(n)); // error
}

сообщение об ошибке clang:

ошибка: ссылка на значение типа int не может привязаться к значению типа int

Мне, decltype(auto) имеет только три возможных типа вывода:

  1. auto
  2. auto&
  3. auto&&

Почему f4 ошибка, в то время как все остальные три в порядке?

1 Ответ

0 голосов
/ 11 декабря 2018

Это ошибка GCC .

decltype(auto) = e эквивалентно decltype(e) и дает объявленный тип e.

auto работает как параметр шаблона, что означает, что auto&& совпадает с T&& (ссылка на пересылку) для изобретенного параметра шаблона.

Для f1 тип возвращаемого значения выводится на int.

Для f2 тип возврата auto& эквивалентен T& с выведенным T=int, который является типом lvalue e, здесь вы привязываете int& к e.

Для f3 учтите это:

auto&& t = n;
static_assert(std::is_same_v<decltype(t), int&>); // true

для обоих возвращаемых значений f3, auto&& эквивалентно придуманному параметру шаблона T&&, который является ссылкой для пересылки, который инициализируется lvalue,yield T& с выведенным T=int, затем снова ... привязка int& к lvalue e.

Теперь для f4 рассмотрим это:

int&& r = 9;
static_assert(std::is_same_v<decltype(r), int&&>); // true (1)

decltype(auto) t = r; // fail with the same error you got.

параметр f4 также является ссылкой для переадресации T&&, которая инициализируется значением xvalue std::move(n), это выводит T=int, что приводит караметр int&& e.Тип возврата как decltype(auto) с return e означает, что фактическое возвращение равно decltype(e), тогда, как вы можете видеть (1), истинно, то же самое верно для decltype(e), это означает, что фактическое возвращение f4это int&& ... и есть проблема, f4 пытается связать rvalue int&& с lvalue e, что запрещено.

Вы также можете взглянуть на @ StoryTeller ответ за ошибку в GCC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...