0

在堆栈溢出中已经有一些与此类似的问题,但似乎没有什么可以直接回答我的问题。如果我重新发布,我深表歉意。

我想用这些方法的部分模板特化来重载模板化类的一些方法(带有 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':无法将函数定义与现有声明匹配

谢谢 :)

4

3 回答 3

6

如果不定义类模板本身的部分特化,就不能部分特化成员函数。请注意,模板的部分特化仍然是模板,因此当编译器看到 时Test<T, float>,它期望类模板的部分特化。

--

C++ 标准 (2003) 中的 $14.5.4.3/1 说,

类模板偏特化成员的模板参数列表应与类模板偏特化的模板参数列表匹配。类模板偏特化成员的模板实参列表应与类模板偏特化的模板实参列表匹配。类模板特化是一个独特的模板。类模板部分特化的成员与主模板的成员无关。应定义以需要定义的方式使用的类模板偏特化成员;主模板成员的定义永远不会用作类模板部分特化成员的定义。类模板部分特化的成员的显式特化以与主模板的显式特化相同的方式声明。

然后标准本身给出了这个例子,

// 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() { }

我希望标准中的引用以及示例能够很好地回答您的问题。

于 2011-03-05T19:07:46.387 回答
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实现中调用。

如果您想要完整的通用性,那么类似地使用具有静态帮助器成员函数的帮助器类,并部分专门化该帮助器类。

干杯&hth.,

于 2011-03-05T20:42:37.210 回答
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
}
于 2013-01-02T12:40:56.617 回答