2011-03-05 50 views
0

有几个问题已经与堆栈溢出相似,但似乎没有任何东西可以直接回答我的问题。如果我正在转贴,我很抱歉。C++ - 使用该方法的部分特化的超载模板化类方法

我想重载模板类(有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: '测试::设置':无法定义的功能匹配到一个现有的声明

谢谢:)

回答

1

你素描的特定问题很简单:

template< class T > 
inline T foo(T const& v) { return v; } 

template<> 
float foo(float const& v) { return v+0.5; } 

然后从你的Test::Set实现中调用foo

如果你想要完整的概括性,那么类似地使用带有静态助手成员函数的助手类,并部分地专门化该助手类。

干杯&心连心,

+0

这是一个好主意。谢谢 :) – JBeFat 2011-03-05 20:51:58

5

你不能部分地专门化一个成员函数,而没有定义类模板本身的局部特化。请注意,模板的部分特化是STILL模板,因此当编译器看到Test<T, float>时,它需要对类模板进行部分特化。

-

$ 14.5.4.3/1从C++标准(2003)表示,

类模板的 构件的模板参数列表中的部分 专业化应匹配 模板参数列表 模板部分专业化。的 成员的 模板参数列表类模板部分 专业化应匹配类 模板部分特例的 模板参数列表。 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() { } 

我希望从标准的报价与示例一起回答你的问题很好。

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 
}