2016-08-25 14 views
6

Compiler: TDM-gcc-5.1.0 (SJLJ odwijania)Nie można użyć declval w typeid dla TDM-GCC

Grałem około z declval i zauważyłem, że nie udało mi się go używać w sytuacji, gdy powinien działać: jako argument do typeid().

W poniższym kodzie używam declval dla jednego z podstawowych przypadków użycia: w celu uzyskania typu zwrotu metody bez przechodzenia przez instancję. Błąd pojawia się komunikat static_assert z declval, ale to powinno być niemożliwe, ponieważ typeid() nie ocenia to argumentem w tym przypadku:

#include <typeinfo> 
#include <utility> 

struct Foo 
{ 
    int func(); 
}; 

int main() 
{ 
    typeid(std::declval<Foo>().func()); 
} 

nie skompilować dla mnie (gdy skompilowany z -std=c++14). Moim jedynym przypuszczeniem jest, że albo znalazłem błąd kompilatora, albo zrobiłem coś oczywiście nie tak i nie widzę tego. Jeśli to drugie, moje przeprosiny.

EDIT: Dzięki Ildjarn za pomoc mnie, rozwiązaniem jest użycie decltype, więc ostatni wiersz kodu staje:

typeid(decltype(std::declval<Foo>().func())); 

i to działa dobrze. Jednak teraz moje pytanie brzmi: jak to się stało? Zarówno typeid(), jak i decltype() są niejednoznacznymi kontekstami, więc nie jestem pewien, na czym polega różnica.

+1

Wypróbuj 'typid (decltype (std :: declval () .func()));' – ildjarn

+0

Ah, to działa! Zastanawiam się, dlaczego tak jest ... –

+2

Od [cppreference] (http://en.cppreference.com/w/cpp/language/typeid): "Jeśli' expression' nie jest wyrażeniem glvalue typu polimorficznego, 'typeid' nie ocenia wyrażenia [.] ". Myślę o błędzie kompilatora. – Quentin

Odpowiedz

4

To błąd kompilatora.

Rozwiązanie wokół niego polega na użyciu decltype() wokół wyrażenia. Zarówno decltype(), jak i typeid() (w tym przypadku wyrażenia nie-polimorficzna-glwartacja) są niejednoznacznymi kontekstami, co nie powinno mieć znaczenia, co powoduje, że jest to błąd. Używanie decltype() tutaj działa jako rodzaj "nieocenionego bufora kontekstowego", i w jakiś sposób typeid() lubi to lepiej.

Cóż, czas skontaktować się z TDM w tej sprawie. Ten błąd nie jest problemem TDM, jest to błąd wanilii (dzięki ildjarn).

+1

Ten błąd [repros na wyższym GCC] (http://coliru.stacked-crooked.com/a/5b9b51852babf848), aczkolwiek z inną manifestacją. Wygląda na to, że kompilator próbuje ocenić 'std :: declval', powodując błąd, zanim zdecyduje, że działa w nieuznanym kontekście, który nie spowodowałby błędu. (Ahh, uwielbiam C++.) W każdym razie nie sądzę, że TDM ma tu jakąś rolę do odegrania. – ildjarn

Powiązane problemy