2016-08-25 17 views
6

Derleyici için TypeId içinde declval kullanılamıyor: TDM-GCC-5.1.0 (SJLJ gevşemek)TDM-GCC

Ben declval ile de oynuyordum ve ben bağlamda nerede kullanmak mümkün olduğunu fark Çalışmalı: typeid()'a bir argüman olarak.

Aşağıdaki kodda, birincil kullanım durumlarından biri için declval kullanıyorum: bir yöntemden geçmeden bir yöntemin dönüş türünü elde etmek için. Ben olsun hata declval ait static_assert mesajı olmakla typeid() bu durumda argüman var değerlendirmek değil çünkü bu imkansız olmalıdır: (-std=c++14 ile derlenmiş olduğunda) Bu benim için derleme değil

#include <typeinfo> 
#include <utility> 

struct Foo 
{ 
    int func(); 
}; 

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

. Tek tahminim ya bir derleyici hatası buldum ya da açık bir şekilde yanlış bir şey yaptım ve göremiyorum. Eğer ikincisiyse, özür dilerim.

DÜZENLEME: Teşekkür bana yardım ettiğin için ildjarn için, çözüm decltype kullanmaktır, böylece kodunun son satırı haline gelir:

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

ve bu güzel çalışıyor. Ancak şimdi sorum şu: Nasıl oldu? typeid() ve decltype() öğelerinin ikisi de değerlendirilmemiş bağlamlardır, dolayısıyla farkın ne olduğundan emin değilim.

+1

Type type (decltype (std :: declval () .func())); ' – ildjarn

+0

Ah, işte! Merak ediyorum neden ... –

+2

[cppreference] 'dan (http://en.cppreference.com/w/cpp/language/typeid): "If ifadesi, polimorfik tipte bir" glite "ifadesi değilse," typeid " [.] ifadesini değerlendirmez. Derleyicinin hatasını düşünüyorum. – Quentin

cevap

4

Bu bir derleyici hatasıdır.

Buradaki çözüm, ifade etrafında decltype() kullanmaktır. Hem decltype() hem de typeid() (bu polimorfik olmayan glival bir ifade durumunda), bir fark yaratmamalı olan, bu bir hata yapan, değerlendirilmemiş bağlamlardır. decltype()'u kullanarak, "derecelendirilmemiş bir içerik arabelleği" gibi davranır ve bir şekilde typeid() bunu daha iyi beğenir. Bu konuda TDM ile temasa geçme vakti gelmiştir. Bu hata TDM'nin sorunu değil, bir vanilya böceği (teşekkürler ildjarn).

+1

Bu hata [upstream GCC üzerinde repros] (http://coliru.stacked-crooked.com/a/5b9b51852babf848), farklı bir tezahür ile de olsa. Derleyicinin 'std :: declval'ı değerlendirmeye çalıştığı ve hataya yol açmayacak olan, değerlendirilmemiş bir bağlamda çalışmaya karar vermeden önce bir hataya neden olduğu görülecektir. (Ahh, C++'yı seviyorum.) Her durumda, TDM'nin burada oynamak için bir parçası olduğunu sanmıyorum. – ildjarn