2015-02-10 5 views
13

У меня есть код, который не работает под 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, как я ожидал.

Задание типа возврата в качестве «строки» вместо decltype (auto) в Visual Studio исправляет его, также как и использование remove_reference_t при возврате f() внутри test1.

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

Правильная оценка?


КОНЦЕ EDIT:

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

cout << test1(zero_params) << endl; 

к:

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

Правильно, 'f()' является prvalue, поэтому 'decltype' должен выводить' std :: string', а не 'std :: string &&'. –

+3

Отправьте сообщение об ошибке в [MS Connect] (https://connect.microsoft.com/VisualStudio/) и разместите ссылку здесь. Этот _really_ должен быть исправлен до того, как VS2015 перейдет в RTM, если 'decltype (auto)' будет чем-то иным, чем бесполезным ... – ildjarn

+0

К сожалению, MS Connect сообщает мне, что я не уполномочен отправлять отчеты об ошибках. Однако в Visual Studio я уже сделал следующее самое лучшее - отправил отзывы, используя их «хмурое лицо», включая скриншот тестового кода с описанием. К сожалению, я не думаю, что этот метод можно отслеживать? Надеюсь, кто-то передает его в нужное отделение – qeadz

ответ

2

Таким образом, based on the comments можно сделать:

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

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

В обходных путях:

  • Не используйте decltype (авто) для функции возвращаемого типа
  • Wrap функции в лямбда-выражении перед передачей это в
+0

Можем ли мы получить эти комментарии, интегрированные в этот ответ? Комментарии являются временными. –

+1

https://connect.microsoft.com/VisualStudio/feedback/details/1124457/decltype-auto-deducing-wrong-type-in-some-cases –

Смежные вопросы