2015-02-10 8 views
13

Mam trochę kodu, który nie działa pod VS2015, ale działa pod GCC. Jestem prawie pewien, że błąd dotyczy Visual Studio, ale chcę mieć pewność, że moje rozumienie decltype (auto) jest poprawne.destruktor wywołany przed tymczasowym powinien być poza zakresem

#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; 
} 

W Visual Studio ciąg zwracany przez zero_parametrów jest wydedukowany jako referencja rwartości. Ponadto destruktor tego obiektu jest wywoływany wewnątrz test1(), gdzie następuje powrót z wywołania f (co wydaje się rozsądnym miejscem do zniszczenia obiektu & &).

Pod GCC zwracany ciąg nie jest wydedukowany jako referencja rwartości. Destruktor jest wywoływany po użyciu w instrukcji cout, jak się spodziewałam.

Określenie typu zwracanego jako 'string' zamiast decltype (auto) w Visual Studio naprawia go, podobnie jak przy użyciu remove_reference_t przy powrocie f() wewnątrz test1.

Moje oczekiwanie byłoby, że GCC jest poprawny jako podpis funkcja zero_params() jest łańcuch, a nie ciąg & & więc spodziewałbym się bez odniesienia do „bańki się” do typu zwracanej test1 jeśli używa decltype (automatyczny).

Czy to jest poprawna ocena?


LATE EDIT:

Innym sposobem znalazłem się obejść ten problem z VS2015 jest zawinąć funkcję nadane test1 w lambda:

cout << test1(zero_params) << endl; 

do:

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

W prawo, 'f()' jest prwartością, więc 'decltype' powinien wydedukować' std :: string' zamiast 'std :: string &&'. –

+3

Proszę zgłosić raport o błędzie na [MS Connect] (https://connect.microsoft.com/VisualStudio/) i zamieścić link tutaj. To _really_ musi zostać naprawione zanim VS2015 przejdzie do RTM, jeśli 'decltype (auto)' ma być czymkolwiek innym niż bezużytecznym ... – ildjarn

+0

Niestety MS Connect mówi mi, że nie mam uprawnień do wysyłania raportów o błędach. Jednak w Visual Studio zrobiłem już następną najlepszą rzecz - przesłałem informację zwrotną za pomocą ich "frowny face", w tym zrzut ekranu kodu testowego z opisem. Niestety nie sądzę, że ta metoda jest łatwa do śledzenia? Mam nadzieję, że ktoś przekazuje go do właściwego działu – qeadz

Odpowiedz

2

Tak więc based on the comments możemy wywnioskować:

błąd jest, że:

  • Kompilator powinien wywnioskować typ zwracany będzie ciąg
  • Rzeczywiście wydedukował go jako ciąg & &
  • W ten sposób zniszczona wartość przedwcześnie

Do obejścia to:

  • Nie używaj decltype (automatyczny) dla funkcji za typ zwracany
  • Wrap funkcja w wyrażeniu lambda przed przekazaniem to w
+0

Czy możemy włączyć te komentarze do tej odpowiedzi? Komentarze są tymczasowe. –

+1

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

Powiązane problemy