2

是否可以专注于某些(不是全部)类模板参数?

例如:

template <typename T, typename U>
class TC
{
public:
 void Foo();
};

template <typename T, typename U>
void TC<T, U>::Foo()
{

}

template <???, typename U>
void TC<int, U>::Foo()
{
  //Want this defined for all U but only when T is int.
}

int main(int argv, char * args [])
{
 TC<int, char> tc;
 return 0;
}
4

3 回答 3

3

通常你可以只特化类模板的一些模板参数,这称为“部分特化”。执行此操作时,您会创建一个新的、专门的模板版本,它会“覆盖”通用版本。

在您的情况下,您似乎只想专门化模板的一部分,即Foo()方法,但这是不可能的。你必须专攻整个TC班级:

// specialization for T=int
template <typename U>
class TC<int, U> {
public:
  void Foo();
};

// implementation of Foo() for the specialized template
template <typename U>
void TC<int, U>::Foo()
{
  //Want this defined for all U but only when T is int.
}
于 2010-02-08T07:08:18.247 回答
1

对于课程,是的。对于函数,no 和 yes。

部分模板特化对于类来说很好,但对于全局函数来说就有点棘手了。

对于类,您只需从模板参数列表中省略专门的参数并将其包含在类定义中:

// General template class for a vector
template <class T, int N>
struct Vector
{
  T e[N];
};

// Specialization for N=3
template <class T> // omit the N
struct Vector<T, 3> // and include it here
{
  T e[3];

  static Vector<T, 3> cross(const Vector<T, 3>& a, const Vector<T, 3>& b)
  {
    return Vector<T, 3>( a.e[1] * b.e[2] - a.e[2] * b.e[1],
                         a.e[2] * b.e[0] - a.e[0] * b.e[2],
                         a.e[0] * b.e[1] - a.e[1] * b.e[0] );

  }
};

对于全局函数,您不能这样做。您可以定义一个完全通用的函数,也可以定义一个完全特化的函数——不允许对函数进行部分特化。

但是,您可以通过将函数创建为部分特化类的静态函数的代理来部分特化该函数。

例如

template <class A, class B>
void foo(A a, B b)
{
  foo_impl::fun(a, b);
}

template <class A, class B>
struct foo_impl
{
  static void fun(A a, B b)
  {
    // real implementation here
  }
};

然后,您可以以任何您想要的方式进行专业化foo_impl,这将反映在foo.

于 2010-02-08T10:08:54.737 回答
0

如果您只想专门化该类的一部分,则需要原始类来提供挂钩。它通常被描述为TraitsPolicies取决于实现。

Traits是引用给定类型的某些属性(有时是方法)的类,并且没有显式传递。STL 中的一个示例是std::iterator_traits<It>.

Policy是作为模板参数传递的类,用于实现许多功能。STL 中的一个示例std::less<int>位于std::set<int, std::less<int> >.

一般来说,Policy类的使用是显式的,而 a 的使用Traits是隐式的……因此我更喜欢前者而不是后者。

如果你的类不使用这些钩子,那么报告sth部分专业化的答案并注意部分意味着一些参数仍然是模板,而不是你只希望专业化类的一部分,因为确实你必须重新定义一切.

于 2010-02-08T09:59:20.403 回答