9

我想专门化一个具有以下功能的类模板:

template <typename T>
class Foo
{
public:
    static int bar();
};

该函数没有参数,并应根据 Foo 的类型返回结果。(在这个玩具示例中,我们返回类型的字节数,但在实际应用程序中,我们希望返回一些元数据对象。)特化适用于完全指定的类型:

// specialization 1: works
template <>
int Foo<int>::bar() { return 4; }

// specialization 2: works
template <>
int Foo<double>::bar() { return 8; }

// specialization 3: works
typedef pair<int, int> IntPair;
template <>
int Foo<IntPair>::bar() { return 2 * Foo<int>::bar(); }

但是,我想将其推广到依赖(其他)模板参数本身的类型。添加以下特化会产生编译时错误(VS2005):

// specialization 4: ERROR!
template <>
template <typename U, typename V>
int Foo<std::pair<U, V> >::bar() { return Foo<U>::bar() + Foo<V>::bar(); }

我假设这不是合法的 C++,但为什么呢?有没有办法优雅地实现这种模式?

4

2 回答 2

7

部分特化仅对类有效,对函数无效。

解决方法:

template <typename U, typename V>
class Foo<std::pair<U, V> > { 
public:
 static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};

如果您不想完全专业化类,请使用辅助结构

template<class T>
struct aux {
  static int bar();
};

template <>int aux <int>::bar() { return 4; }
template <>int aux <double>::bar() { return 8; }

template <typename U, typename V>
struct aux <std::pair<U, V> > { 
  static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};

template<class T>
class Foo : aux<T> {
  // ... 
};
于 2009-11-25T15:07:02.140 回答
5

它在 C++ 中是完全合法的,它是部分模板专业化。
删除template <>,如果它不存在,则添加显式类模板特化,它应该在 VS2005 上编译(但不是在 VC6 中)

// explicit class template specialization
template <typename U, typename V>
class Foo<std::pair<U, V> >
{
public:
    static int bar();
};

template <typename U, typename V>
int Foo<std::pair<U, V> >::bar() { return Foo<U>::bar() + Foo<V>::bar(); }
于 2009-11-25T15:03:02.503 回答