implizite Instanziierung einer undefinierten Vorlage 'Klasse'

Beim Versuch, Funktionen für const- und non-const-Template-Argumente in meiner Bibliothek anzubieten, bin ich auf ein seltsames Problem gestoßen. Der folgende Quellcode ist ein minimales Beispielphänomen:

#include <iostream>


template<typename some_type>
struct some_meta_class;

template<>
struct some_meta_class<int>
{
    typedef void type;
};



template<typename some_type>
struct return_type
{
    typedef typename some_meta_class< some_type >::type test;

    typedef void type;
};



template<typename type>
typename return_type<type>::type foo( type & in )
{
    std::cout << "non-const" << std::endl;
}

template<typename type>
void foo( type const & in )
{
    std::cout << "const" << std::endl;
}


int main()
{
    int i;

    int const & ciref = i;
    foo(ciref);
}

Ich habe versucht, eine Nicht-Konstanten-Version und eine Konstanten-Version für foo zu implementieren, aber leider lässt sich dieser Code unter CLANG 3.0 und gcc 4.6.3 nicht kompilieren.

main.cpp: 18: 22: Fehler: Implizite Instanziierung der undefinierten Vorlage 'some_meta_class'

Aus irgendeinem Grund möchte der Compiler die Nicht-Konstanten-Version von foo für eine Konstanten-Int-Referenz verwenden. Dies führt offensichtlich zu dem obigen Fehler, da für some_meta_class keine Implementierung vorhanden ist. Das Seltsame ist, dass, wenn Sie eine der folgenden Änderungen vornehmen, der Code gut kompiliert wird und funktioniert:

Kommentiere die nicht konstante Version aus / entferne sieDekomprimieren / entfernen Sie das typedef von return_type :: test

Dieses Beispiel ist natürlich minimalistisch und rein akademisch. In meiner Bibliothek bin ich auf dieses Problem gestoßen, weil die Versionen const und non-const unterschiedliche Typen zurückgeben. Ich habe dieses Problem gelöst, indem ich eine Helferklasse verwendet habe, die teilweise spezialisiert ist.

Aber warum führt das obige Beispiel zu einem so merkwürdigen Verhalten? Warum möchte der Compiler nicht die Nicht-Konstanten-Version verwenden, bei der die Konstanten-Version gültig ist und besser passt?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage