tanımında varsayılan türe sahip bir şablonla mücadele ediyor gcc ile bir sorunu saptamak için çok sayıda saat harcadım. Clang'un kaçırmış olabileceği konusunda daha fazla uyarı aramak için kod tabanımızı başka bir derleyiciyle test etmek istedim. Projenin neredeyse yarısının, şablon argümanı kesintisinin başarısızlığı nedeniyle derlenmeyi bırakması beni şaşırttı. Burada davanımı en basit kod parçası haline getirmeyi denedim. GCC'nin tüm sürümleri,
#include <type_traits>
struct Foo
{ };
// This is a template function declaration, where second template argument declared without a default
template <typename T, typename>
void foo(const Foo & foo, T t);
// This is a template function definition; second template argument now has a default declared
template <typename T, typename = typename std::enable_if<1>::type>
void foo(const Foo & foo, T t)
{
}
int main(int argc, char ** argv)
{
foo(Foo{}, 1);
return 0;
}
std::enable_if<1>
bir
1
geçiyoruz. Açıkçası, önemi olmayan şeyleri karmaşıklaştırmak için sabit bir değerdir.
Bu kod parçası derler [1] çınlama (4.0 üzerinden 3.4), ICC (16, 17), Visual C++ ile (19.00.23506). Temel olarak, gcc (4.8 - 7.1) dışındaki herhangi bir C++ 11 derleyiciyi bu kod parçasını derlemedim.
Soru şu ki, kim haklı ve kim yanlış burada? gcc standarda göre davranıyor mu?
Açıkçası bu önemli bir konu değildir. Bildirime kolayca std::enable_if
'u taşıyabilirim. Tek kurban estetik olurdu. Ancak, uygulamada kütüphane işlevinin kullanıcısı için hemen geçerli olmayan çirkin 100 karakter uzunluğunda std::enable_if
kodunun gizlenebilmesi güzel bir şey. godbolt.org üzerinde
Canlı bir örnek.
En.cppreference.com'da [varsayılan şablon argümanları] için (http://en.cppreference.com/w/cpp/language/template_parameters#Default_template_arguments) »Bildirimlerde ve tanımda görünen varsayılan şablon argümanları varsayılan işlev argümanlarına benzer şekilde birleştirilir «. [Varsayılan işlev argümanları] için (http://en.cppreference.com/w/cpp/language/default_arguments) "... işlev bildiriminin parametre listesinde bir parametrenin aşağıdaki sözdizimini kullanarak gösterildiğini gördüm ...« . Eğer bunu doğru olarak yorumluyorsam, beyannamede * varsayılan argümana * sahip olursunuz. https://godbolt.org/g/kXNbYi: –
@HenriMenke, bu ** gcc ** işlevleri için çalışır. Görünüşe göre, ** gcc ** fonksiyonlar ve şablonlar için çifte standartlara sahip ... – GreenScape
@HenriMenke 14.1/10'da "template <...> class A" örneğine bakınız. G ++ 'da olduğu gibi çalışır, ancak bir işlevi bir sınıfla değiştirmezseniz. –