在堆栈溢出上已经有一些问题已经类似于此了,但似乎没有什么能直接回答我的问题。如果我要重新发布,我会道歉。
我想使用这些方法的部分模板特化来重载模板化类的一些方法(带有2个模板参数)。我无法弄清楚正确的语法,并开始认为这是不可能的。我以为我会在这里发帖,看看能不能得到确认。
要遵循的示例代码:
template <typename T, typename U>
class Test
{
public:
void Set( T t, U u );
T m_T;
U m_U;
};
// Fully templated method that should be used most of the time
template <typename T, typename U>
inline void Test<T,U>::Set( T t, U u )
{
m_T=t;
m_U=u;
}
// Partial specialisation that should only be used when U is a float.
// This generates compile errors
template <typename T>
inline void Test<T,float>::Set( T t, float u )
{
m_T=t;
m_U=u+0.5f;
}
int _tmain(int argc, _TCHAR* argv[])
{
Test<int, int> testOne;
int a = 1;
testOne.Set( a, a );
Test<int, float> testTwo;
float f = 1.f;
testTwo.Set( a, f );
}
我知道我可以写出整个班级的部分专业,但这有点糟透了。这样的事情可能吗?
(我正在使用VS2008) 编辑:这是编译错误 错误C2244:'Test :: Set':无法将函数定义与现有声明匹配
谢谢:)
答案 0 :(得分:5)
如果没有定义类模板本身的部分特化,则不能部分地专门化成员函数。请注意,模板的部分特化是STILL模板,因此当编译器看到Test<T, float>
时,它期望类模板的部分特化。
-
来自C ++标准(2003)的$ 14.5.4.3 / 1表示,a的模板参数列表 类模板部分的成员 专业化应匹配 模板参数列表的类 模板部分专业化。 模板参数列表的成员 一个类模板部分 专业化应匹配 模板参数列表的类 模板部分专业化。 :一种 类模板专业化是一个 独特的模板。的成员 类模板部分特化 与成员无关 主要模板。类模板 部分专业化成员 以需要的方式使用 定义应定义;该 主要成员的定义 模板永远不会用作定义 对于类模板的成员 部分专业化。一个明确的 一个成员的专业化 模板部分专业化是 以与a相同的方式声明 主要的显性专业化 模板。
然后标准本身给出了这个例子,
// primary template
template<class T, int I> struct A {
void f();
};
template<class T, int I> void A<T,I>::f() { }
// class template partial specialization
template<class T> struct A<T,2> {
void f();
void g();
void h();
};
// member of class template partial specialization
template<class T> void A<T,2>::g() { }
我希望标准中的引文和示例能够很好地回答您的问题。
答案 1 :(得分:1)
您正在草拟的特殊问题很简单:
template< class T >
inline T foo( T const& v ) { return v; }
template<>
float foo( float const& v ) { return v+0.5; }
然后从foo
实施中致电Test::Set
。
如果您想要完整的通用性,那么类似地使用带有静态助手成员函数的助手类,并部分地专门化该助手类。
干杯&amp;第h。,
答案 2 :(得分:0)
如果您不想在代码中引入其他函数,方法或类,还有部分特化问题的另一种解决方案。
#include <type_traits>
template <typename T1, typename T2>
class C
{
void f(T1 t1);
}
template <typename T1, typename T2>
void C<T1, T2>::f(T1 t1)
{
if (std::is_same<T2, float>::value)
// Do sth
else
// Do sth
}