Примечание: это, по-видимому, является отправкой проблемы: С++ - перегружает шаблонный метод класса с частичной спецификацией этого метода
У меня возникла проблема, с которой я сталкиваюсь с специализацией по шаблону С++ вплоть до простого случая.
Он состоит из простого двухпараметрического шаблона класса Thing
, где я хотел бы специализировать Thing<A,B>::doSomething()
для B=int
.
#include <cstdio>
//
// A 3-parameter template class.
//
template <class A, class B>
class Thing
{
public:
Thing(A a, B b) : a_(a), b_(b) {}
B doSomething();
private:
A a_;
B b_;
};
//
// The generic case works as expected.
//
template <class A, class B>
B Thing<A,B>::doSomething()
{
return b_;
}
//
// This specialization does not work!
//
template <class A>
int Thing<A,int>::doSomething()
{
return b_+1;
}
int main( int argc, char** argv )
{
// Setup our thing.
Thing<double,int> thing(1.0,2);
// This doesn't compile - but works with the generic case.
printf("Expecting 3, and getting %i\n", thing.doSomething());
// Clean up.
return 0;
}
К сожалению, g++
выходит с ошибкой:
partial_specialization.cpp:30: error: invalid use of incomplete type ‘class Thing<A, int>’
partial_specialization.cpp:8: error: declaration of ‘class Thing<A, int>’
Компилятор clang++
является немного более подробным, но имеет ту же проблему:
partial_specialization.cpp:30:19: error: nested name specifier 'Thing<A, int>::' for declaration does not
refer into a class, class template or class template partial specialization
int Thing<A,int>::doSomething()
~~~~~~~~~~~~~~^
partial_specialization.cpp:32:12: error: use of undeclared identifier 'b_'
return b_+1;
^
2 errors generated.
Я прочитал и понял, что частичные специализированные шаблоны по функциям недопустимы, но я думал, что в этом случае я частично специализируюсь на классах Thing
.
Любые идеи?
Что я сделал: Обходной путь, определенный по ссылке, предоставленной принятым ответом:
template< class T >
inline T foo( T const & v ) { return v; }
template<>
inline int foo( int const & v ) { return v+1; }
//
// The generic case works as expected.
//
template <class A, class B>
B Thing<A,B>::doSomething()
{
return foo(b_);
}