Şablon şablonu sınıfıyla GCC / C ++ 17'de sorun


10

Aşağıdaki aşırı yüklenmeleri göz önünde bulundurun

template<typename T>
bool test() {
    return true;
}

template<template<typename ...> class T>
bool test() {
    return false;
}

Birincisi normal sınıflar için, ikincisi ise örneklenmemiş şablonlar için çalışır. Örneğin:

    std::cout<<test<int>()<<std::endl; <-- this yields 1
    std::cout<<test<std::list>()<<std::endl; <--this yields 0

Şimdi aşağıdaki şablon işlevini göz önünde bulundurun:

template<typename U>
bool templfun(){
    struct A{
        bool f(){
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>();  // <-- this is ok
}

GCC'de belirsiz aşırı yük çözünürlüğü için bir hata verirken Clang derler. İlginçtir, ikinci test () çağrısı hata üretmez (GCC'de bile). Dahası, eğer template<typename U>templfun üstündeki şeyi kaldırırsam, gcc şikayet etmeyi bırakır.

Bu GCC ile ilgili bir hata mı yoksa yasa dışı kod mu?

Yanıtlar:


4

GCC yanlış; struct ABir olan Templated varlık ama açıkça bir şablon (bir ile başlamıyorsa olarak template, bu nedenle belirsizlik yoktur anahtar kelime).

Onaylamak için, G ++ öğesinin şablon şablonu aşırı yüklemesini kullanmaya çalıştığını görmek için type parametresini yeniden adlandırabiliriz.

template <typename X>
bool test() {
    return true;
}

template <template <typename...> class Y>
bool test() {
    return false;
}

template <typename U>
bool templfun() {
    struct A {
        bool f() {
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>(); // <-- this is ok
}

bool run() {
    return templfun<int>();
}

G ++ çıktısı: ( godbolt bağlantısı )

<source>:15:27: error: call of overloaded 'test<templfun() [with U = int]::A>()' is ambiguous
   15 |             return test<A>(); // <-- this gives an error
      |                    ~~~~~~~^~

<source>:2:6: note: candidate: 'bool test() [with X = templfun() [with U = int]::A]'
    2 | bool test() {
      |      ^~~~

<source>:7:6: note: candidate: 'bool test() [with Y = templfun()::A]'
    7 | bool test() {
      |      ^~~~

Açıkçası " candidate: 'bool test() [with Y = templfun()::A]'" sahte.

Yerel türlere C ++ 11'den önce şablon bağımsız değişkenleri olarak izin verilmediğine dikkat edin (bkz. C ++ 03 § 14.3.1.2), böylece G ++ uygulamasının karmaşıklığını açıklayabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.