instanciação implícita do template indefinido 'class'

Ao tentar oferecer funções para argumentos de modelo const e non-const em minha biblioteca, encontrei um problema estranho. O código-fonte a seguir é um fenômeno de exemplo mínimo:

#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);
}

Eu tentei implementar uma versão não-const e uma versão const para foo, mas infelizmente este código não irá compilar no CLANG 3.0 e gcc 4.6.3.

main.cpp: 18: 22: error: instanciação implícita do template indefinido 'some_meta_class'

Então, por alguma razão, o compilador quer usar a versão não const do foo para uma referência int-const. Isso obviamente leva ao erro acima porque não há implementação para some_meta_class. O estranho é que, se você fizer uma das seguintes alterações, o código compilará bem e funcionará:

descomente / remova a versão não constdescompactar / remover o typedef de return_type :: test

Este exemplo é claro, acadêmico minimalista e puro. Na minha biblioteca me deparei com esse problema porque a versão const e non-const retornam tipos diferentes. Eu gerenciei esse problema usando uma classe auxiliar parcialmente especializada.

Mas por que o exemplo acima resulta em um comportamento tão estranho? Por que o compilador não quer usar a versão não const onde a versão const é válida e combina melhor?

questionAnswers(1)

yourAnswerToTheQuestion