неявная реализация неопределенного шаблона 'class'

При попытке предложить функции для константных и неконстантных аргументов шаблона в моей библиотеке я натолкнулся на странную проблему. Следующий исходный код является минимальным примером явления:

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

Я попытался реализовать неконстантную версию и константную версию для foo, но, к сожалению, этот код не скомпилируется на CLANG 3.0 и gcc 4.6.3.

main.cpp: 18: 22: ошибка: неявное создание неопределенного шаблона 'some_meta_class'

Поэтому по какой-то причине компилятор хочет использовать неконстантную версию foo для const int-ссылки. Это, очевидно, приводит к вышеприведенной ошибке, потому что для some_meta_class нет реализации. Странно то, что если вы сделаете одно из следующих изменений, код скомпилируется хорошо и работает:

раскомментировать / удалить неконстантную версиюuncomemnt / удалить определение типа return_type :: test

Этот пример, конечно, минималистичный и чисто академический. В моей библиотеке я столкнулся с этой проблемой, потому что константная и неконстантная версии возвращают разные типы. Я справился с этой проблемой, используя вспомогательный класс, который частично специализирован.

Но почему приведенный выше пример приводит к такому странному поведению? Почему компилятор не хочет использовать неконстантную версию, где константная версия верна и лучше соответствует?

Ответы на вопрос(1)

Ваш ответ на вопрос