Подтвердить что ты не робот

Деструктор, вызванный до временного, должен быть недоступен

У меня есть немного кода, который не работает под VS2015, но работает под GCC. Я уверен, что ошибка связана с Visual Studio, но я хочу быть уверенным, что мое понимание decltype (auto) верное.

#include <iostream>
using namespace std;

string zero_params()
{
  return "zero_params called.";
}

template< typename F >
auto test1( F f ) -> decltype(auto)
{
  return f();
}

int main() {
  cout << std::is_rvalue_reference< decltype(test1(zero_params)) >::value << endl;
  cout << test1(zero_params) << endl;

  cout << "Done!" << endl;
  return 0;
}

В Visual Studio выводится строка, возвращаемая zero_params, как ссылка rvalue. Кроме того, деструктор этого объекта вызывается внутри test1(), где происходит возврат из вызова в f (что кажется разумным местом для уничтожения объекта & &).

В GCC возвращаемая строка не выводится как ссылка rvalue. Деструктор вызывается после использования в инструкции cout, как я ожидал.

Указание типа возвращаемого значения как "string" вместо decltype (auto) в Visual Studio исправляет его, как и using remove_reference_t при возврате f() внутри test1.

Мое ожидание было бы тем, что GCC корректен, поскольку сигнатура функции для zero_params() - это строка, а не строка && так что я бы ожидал, что не-ссылка "пузырится" на возвращаемый тип test1, если он использует decltype (auto).

Является ли это правильной оценкой?


ПОСЛЕДНИЙ РЕДАКТИРОВАНИЕ:

Другим способом, который я нашел, чтобы обойти это с помощью VS2015, является обертка функции, заданной test1 в лямбда:

cout << test1(zero_params) << endl;

в

cout << test1( [](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); } ) << endl;
4b9b3361

Ответ 1

So на основе комментариев, мы можем заключить:

  • Это ошибка в предварительном просмотре VS2015
  • Есть обходные пути
  • Сообщается об ошибке

Исправлена ​​ошибка:

  • Компилятор должен был вывести тип возвращаемого значения в строку
  • Фактически он вывел его как строку &&
  • Таким образом, он преждевременно разрушил значение

Обходные пути:

  • Не используйте decltype (auto) для возвращаемого типа функции
  • Оберните функцию в выражении лямбда перед тем, как передать ее в