2016-11-28 38 views
9

Bu, this sorusundaki bir takiptir.Kontrol edilmiş koruyucu parametre paketleri, uzmanlık durumunda kötü biçimlendirilmiş programların sebebi midir?

#include <type_traits> 

template<typename T, typename... P, typename U = std::enable_if_t<std::is_integral<T>::value>> 
void f() { static_assert(sizeof...(P) == 0, "!"); } 

int main() { 
    f<int>(); 
} 

Bu derler ama [temp.res]/8 göre o, hiçbir teşhis gerekli kötü şekillendirilmiş değildir çünkü:

variadic şablonun her geçerli uzmanlaşma bir gerektiriyor

Aşağıdaki kodu düşünün Boş şablon parametre paketi

Şimdi biraz farklı bir örnek olarak düşünün:

Bu durumda, parametre paketinin boş olmadığı geçerli tam açık bir uzmanlık var.
Bu, kodun artık kötü biçimlendirilmemiş olduğunu söylemek için yeterli midir?


Not: Ben dönüş türü veya benzeri içinde std::enable_if_t koyarak gibi alternatif yollar aramıyorum.

+1

"static", "f" işlevinin özelleştirmesini ** geçersiz ** "sizeof ... (P)! = 0" durumunda yapar. Çok ilginç bir soru! –

+0

@ W.F. Evet. Bağlantılı soru, ilk örnek için ayrıntıları içerir. Beğenmene sevindim. :-) – skypjack

cevap

4

[temp.res]/8 hakkında şablon bildirimi s, varlık değil. Yani, birincil şablonlar ve tekil tek tek; Bu "şablonlar", numaralı numaralı kuralların geçerli bir uzmanlık bilgisine sahip olması şarttır. Aksi takdirde, bu paragraftaki ilk mermi aynı şekilde yorumlanmak zorunda kalacaktı, ki bu kesinlikle niyetini anlamıyordu.

template <typename T> 
void f() {T+0;} // wouldn't be allowed to diagnose this, because there could be an 
       // explicit specialization that doesn't contain this statement...? 
+0

Gerçekten ilginç. Standardı bir kez daha gözden geçireceğim. Çok teşekkür ederim. – skypjack

+0

Bu kadar uzağa gitmeyelim. 'şablon void f() {1 + nullptr; } 'yapardı. Ve senin örneğinin aslında teşhis edilemeyeceğine inanıyorum çünkü 'f () 'geçerli :) –

+0

@ T.C. Bu mu? Başlatıcı, [expr.type.conv]/3 tarafından yönetilir, bu da referans türlerini kendi cümleleriyle engeller; ve/2, "()' başlatıcısı için açık bir şekilde referans türlerini engeller, böylece tutarlı hissedilir. Ayrıca, bir referans referansını nasıl oluşturabileceğinizi ve bunu bir prvalue olarak nasıl sağlayabileceğinizi de görmüyorum. – Columbo