Я не уверен, является ли это ошибкой в Clang 3.2 или нарушением C ++ 03, но кажется, что явное создание экземпляров шаблонных конструкторов для шаблонных классов завершается неудачно, но явное создание экземпляров шаблонных функций классов-шаблонов успешно.
Например, следующее компилируется без проблем с clang ++ и g ++:
template<typename T>
class Foo
{
public:
template<typename S>
void Bar( const Foo<S>& foo )
{ }
};
template class Foo<int>;
template class Foo<float>;
template void Foo<int>::Bar( const Foo<int>& foo );
template void Foo<int>::Bar( const Foo<float>& foo );
template void Foo<float>::Bar( const Foo<int>& foo );
template void Foo<float>::Bar( const Foo<float>& foo );
в то время как следующее компилируется без предупреждения с g ++, но завершается неудачно с clang ++:
template<typename T>
class Foo
{
public:
template<typename S>
Foo( const Foo<S>& foo )
{ }
};
template class Foo<int>;
template class Foo<float>;
template Foo<int>::Foo( const Foo<int>& foo );
template Foo<int>::Foo( const Foo<float>& foo );
template Foo<float>::Foo( const Foo<int>& foo );
template Foo<float>::Foo( const Foo<float>& foo );
В частности, я вижу два сообщения об ошибках вида:
TemplateMember.cpp:12:20: error: explicit instantiation refers to member
function 'Foo<int>::Foo' that is not an instantiation
template Foo<int>::Foo( const Foo<int>& foo );
^
TemplateMember.cpp:9:16: note: explicit instantiation refers here
template class Foo<int>;
^
Это нарушение стандарта или ошибка в clang ++?
Похоже, вы нашли ошибку в GCC. Они оба называют неявно объявленный конструктор копирования:
template Foo<int>::Foo( const Foo<int>& foo );
template Foo<float>::Foo( const Foo<float>& foo );
За [temp.explicit] p4,
Если объявление явного экземпляра присваивает имя неявно объявленной специальной функции-члену (раздел 12), программа некорректна.
Поэтому Clang правильно отклонить этот код.
Других решений пока нет …