模板专业化与模板参数

Bia*_*sta 8 c++ templates template-specialization c++11 c++98

我们假设有一个template班级Foo:

template <typename T>
class Foo {
  void foo();
};
Run Code Online (Sandbox Code Playgroud)

我有另一个templateBar(独立于第一个类):

template <int N>
class Bar {};
Run Code Online (Sandbox Code Playgroud)

让我们说,我想专门foo()为任何Bar类的方法.我写错了:

template <>
template <int N>
void Foo<Bar<N> >::foo() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

编译器指责我,因为类型不完整:

error: invalid use of incomplete type 'class Foo<Bar<N> >'
 void Foo<Bar<N> >::foo() { }
Run Code Online (Sandbox Code Playgroud)

我正在使用C++ 98,但我想知道C++ 11中是否存在不同的解决方案.


注意

我可以解决专门Foo针对泛型的整个类的问题Bar,但是在我必须定义所有方法之后.

示例代码

这不是我想要的,我正在寻找(如果存在)更优雅的解决方案(包括C++ 98和C++ 11),它允许我专门化并实现单个类方法.


编辑:

关于SO的问题没有解释如何专注于模板参数.实际上,我的问题显示了编译器如何抱怨这一点.

max*_*x66 4

对于 C++11,您可以 SFINAE 启用/禁用(使用std::enable_iffoo()非专用Foo类内部的两个不同版本。

在 C++98 中你没有std::enable_if,但你可以模拟它(给我一些时间,我尝试提出一个例子)。抱歉:我的想法行不通,因为此方法需要使用 C++11 创新方法的默认模板参数。

另一种方法是定义一个模板基类Foo(),例如FooBase插入foo()(且仅foo()FooBase和专门化FooBase

另一种方法(也适用于 C++98)可以是标记分派:您可以定义一个唯一的foo()、参数为零的 ,它调用另一个foo(),其参数由 确定T

以下是完整的(C++98可编译)示例

#include <iostream>

struct barWay   {};
struct noBarWay {};

template <int>
struct Bar
 { };

template <typename>
struct selectType
 { typedef noBarWay type; };

template <int N>
struct selectType< Bar<N> >
 { typedef barWay type; };

template <typename T>
struct Foo
 {
   void foo (noBarWay const &)
    { std::cout << "not Bar version" << std::endl; }

   void foo (barWay const &)
    { std::cout << "Bar version" << std::endl; }

   void foo ()
    { foo(typename selectType<T>::type()); }
 };


int main ()
 {
   Foo<int>        fi;
   Foo< Bar<42> >  fb;

   fi.foo();
   fb.foo(); 
 }
Run Code Online (Sandbox Code Playgroud)