2016-03-07 11 views
17

şu bir işlevi döndüren bir işlevi bildirerek yasadışı her iki derleyiciler fırsatlar hem gcc ve clangBir işlev döndüren bir işlev türü yazabilir miyim?

#include <type_traits> 

int foo(); 

int main() 
{ 
    using R = std::result_of_t<decltype(foo)()>; // error 
} 

hata üzerinde derlemek için başarısız olur. Ama ben böyle bir işlevi beyan etmiyorum - sadece türünü yazmaya çalışıyorum - result_of beklediğinden bu yana. Bu gerçekten de hastalanmış mı?

+8

Bence "Her iki derleyicide de hata, bir işlevi döndüren bir işlevi bildirmenin yasa dışılığıyla ilgilenir." gerçek hata – Guiroux

+4

ile değiştirilir Neden sadece 'decltype (foo())' kullanmıyorsunuz? – StenSoft

+3

İşlev, başka bir işlev türünü döndürdüğü bir işlev türü oluşturmanıza izin verilmez. "İşlevler, tür dizisi veya işlev türünde bir döndürme türüne sahip olmayacaktır." Dcl.fct/8 – Simple

cevap

10

Sen varlığın adını atlar bu tür bir değişken veya fonksiyon için sözdizimsel [...] bir deklarasyon

olarak [dcl.name] tanımlanan bir tip-id, geçiyoruz. […] Yapı, bildirimde bir deklare ediciyse, abstract-declarator'daki tanımlayıcıyı görünecek şekilde benzersiz bir şekilde tanımlamak mümkündür. Adlandırılmış tür, varsayımsal tanımlayıcısının türüyle aynıdır.

varsayımsal tanımlayıcı bir tür olması için, varsayımsal deklarasyon ilk etapta bir şekilde biçimlendirilmiş olması gerekir. Ancak [dcl.fct]/10'a göre değil. Bu nedenle, program kötü biçimlendirilmiştir (ve derleyicilerin hata mesajları aslında anlaşılırdır). Bu durum ayrıca, bunun doğrudan (SFINAE dostu) bir hata olduğu anlamına gelen [temp.deduct]/(8.10) tarafından da karşılanmaktadır. Aslında, geçersiz bir tipin kullanımını ima ederek programın kötü biçimlendirilmesini sağlamak için yeterlidir. Örneğin. fonksiyonunu dönen işlev tip işaretçisi yaratarak kötü şekillendirilmiş geçerli:

Yani
using f = int(); 
using t = f(*)(); 

şudur:

struct A {virtual void f() = 0;}; 
using t = A(*)(); 

(Clang bu kabul edilmemelidir Cf GCC hata 17232 işin ilginç tartışma.) .

+1

Bu eel.is şeyi gerçekten seviyorum. – Barry