Почему нельзя вывести аргумент в типе возвращаемого значения функции? - PullRequest
0 голосов
/ 31 мая 2018

Самый очевидный ответ мог бы быть - , потому что стандарт так говорит .
Это нормально, но я оборачиваюсь вокруг этого, чтобы понять причины этого выбора.

Рассмотрим следующий пример:

template<typename T>
struct S { S(T) {} };

S f() { return 0; }

int main() {
    auto s = f();
    (void)s;
}

Не удается скомпилировать с ошибками типа:

ошибка: использование шаблона класса 'S' требует аргументов шаблона;вычет аргументов не разрешен в функции, тип возврата

Довольно легко исправить, это не проблема, что-то вроде этого работает просто отлично:

auto f() { return S{0}; }

Однако я бы хотелхотелось бы понять, что было недостатками в разрешении вывода аргументов шаблона класса и в типах, возвращаемых функциями.
На первый взгляд, это выглядит как глупое ограничение, но я почти уверен, что здесь упущено что-то важное.

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

Только мои волнистые два цента, которые обобщают мое понимание:

В

S f() { return 0; }

S - это не тип, который можно вывести, это просто шаблон.Вы могли бы написать

template<typename T>
S<T> f() { return 0;}

, но теперь очевидно, что для вызова

auto s = f();

нет никакого способа определить, какой тип T должен быть.

0 голосов
/ 31 мая 2018

Почему в типе, возвращаемом функцией, не допускается вычет аргументов?

Поскольку в стандарте так сказано.

Вы можете задать вопрос: почему есть разница?между этими строками кода:

S s = 0;            // OK
S s() { return 0; } // error - even though this is also copy-initializing an "S" from 0

Вы можете придумать неясное объяснение того, почему первое должно быть в порядке и почему не должно быть второго - но принципиально выведение аргумента шаблона класса было предложено только дляадрес первый случай, а не второй.Первый - нормально, потому что стандарт говорит об этом, а второй - ошибка, потому что стандарт так говорит.

Предложено расширение ( P1021 , в разделе "Вывод типа возврата дляфункции "), что бы решить второй случай.Считаете ли вы это хорошей идеей ... ¯ \ _ (ツ) _ / ¯

0 голосов
/ 31 мая 2018

Здесь нет ничего языкового закона: если вы указываете тип возвращаемого значения (а не auto или T, где T - это тип шаблона), этот возвращаемый тип должен быть действительным.позвольте мне привести вам еще более простой, лучший пример:

std::vector function() {
    return std::vector<int>();
}

Очевидно, что он не может скомпилироваться, даже без модных шаблонов, auto и вычетов типов, потому что std::vector не тип, std::vector<int> является.

Когда вы указываете S в качестве типа возвращаемого значения, вы в основном

  • Не допускаете, чтобы компилятор определял сам тип
  • Укажите неверный тип возвращаемого значения, например S не тип, S<int> есть.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...