A
的类层次结构中使用了一个模板类B::C_#
,专门用于create()
的方法A
:
template <typename T>
class A
: public std::map<std::string, double (T::*)() const>
{
...
void create();
...
};
template <typename T>
void A<T>::create()
{ assert(false); }
其中一个子类C_#
(比方说C_0
)直到最近都很棒。一切顺利,直到C_0
决定成为模板。除了create()
专业化之外,他得到了一切。它试图通过以下方式专门化create()
:
template<class N1, class N2>
class C_0: public B<N1, N2>
{
...
}
...
template<class N1, class N2>
some_namespace::A< some_namespace::C_0<N1, N2> >
some_namespace::C_0<N1, N2>::A_;
template <>
void some_namespace::A< C_0<N1, N2> >::create() // line 1151
{
blah_(&C_0<N1, N2>::get_stuff);
}
但C_0
的尝试到目前为止失败了:
C_0.h:1151:45: error: 'N1' was not declared in this scope
C_0.h:1151:49: error: 'N2' was not declared in this scope
C_0.h:1151:51: error: template argument 1 is invalid
C_0.h:1151:51: error: template argument 2 is invalid
C_0.h:1151:53: error: template argument 1 is invalid
C_0.h:1151:63: error: 'create' is not a template function
请帮助可怜的生物克服他的麻烦。
还尝试在专门的C_0
中进行模板方法专业化:
namespace some_namespace
{
class C_0_specialized: public C_0<double_t, size_t>
{};
template <>
void A<C_0_specialized>::create()
{
blah_(&C_0_specialized::get_stuff);
}
}
这次编译,但调用原始方法,即void A<T>::create() { assert(false); }
解决方案
好的,所以我最终在A
模板级别内使用C_0
参数列表对整个模板类C_0
进行了部分特化:
template<class N1, class N2>
class A< C_0<N1, N2> >
{
...
void create()
{
blah_(&C_0<N1, N2>::get_stuff);
}
...
}
原因是:1)不允许对模板方法进行部分特化,因此不可能只对void create()
进行专门化,当类是部分专用的时,所有方法和变量都必须在专业化; 2)在void create()
级别内无法对模板方法C_0
进行显式专门化,因为A
依赖于C_0
模板参数列表; 3)将void create()
专门化移动到C_0_specialized
,可以明确专门化,因为在C_0_specialized
解析模板参数列表时,因为A
的实例(实例化)是不可能的上面代码中的A_
已在模板C_0
中使用,因此A_
无法在A
级别看到C_0
的专业化。这就是为什么在那个级别它调用void create()
的基本版本。由于开销太大,也无法将A_
移至C_0_specialized
级别。
好的是,A
课程并不大,但仍然最好只专注void create()
。
我发现this resource对于解释模板的显式和部分特化之间的差异非常有用。
答案 0 :(得分:2)
首先,您忘了告诉编译器N1
和N2
是类型
template<class N1, class N2>
void some_namespace::A< C_0<N1, N2> >::create() // line 1151
{
blah_(&C_0<N1, N2>::get_stuff);
}
这仍然不起作用,因为没有定义类A<C_0<N1,N2>>
。首先声明。
注意:您确实定义了A<T>
,但这是一般情况,而不是您没有尝试为其定义成员的专业化。
顺便说一句,以下三行绝对没有任何意义。
template<class N1, class N2>
some_namespace::A< some_namespace::C_0<N1, N2> >
some_namespace::C_0<N1, N2>::A_;