我该怎么做这个明确的专业化?

时间:2010-11-25 08:01:29

标签: c++ templates explicit-specialization

可以使用以下设计吗?:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

现在如果有可能我会为doSomething做一些明确的专业化,以便最后我会有一些版本如下:

void doSomething<int>(){
 //do something
}
void doSomething<double>(){
 //do something
}
...etc

这似乎不可能我找不到任何语法来完成这项工作然后我想也许设计应该如下所示,以便所有模板参数都应该传递给模板类本身:

template <typename T,typename Z>
class Test{
 public:
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

然后我尝试了部分特化,甚至没有编译:

template <typename T>
void Test<T,int>::doSomething(){
 //do something
}
template <typename T>
void Test<T,double>::doSomething(){
 //do something
}
...etc

我明确专业化时遇到以下错误:
错误#1:类模板名称后面的模板参数列表必须按模板参数列表中使用的顺序列出参数 错误#2:'Container1':模板参数太少。

6 个答案:

答案 0 :(得分:6)

为明确专门化doSomething,您还必须明确专门化Test

从14.7.3 / 18:

  

明确的专业化   一个班级成员的声明   模板或成员模板   出现在命名空间作用域中的成员   模板和它的一些封闭   类模板可能会保留   非专业,除了   声明不得明确   如果要专门化一个类成员模板   它的封闭类模板不是   明确专业化

答案 1 :(得分:2)

除非其封闭的类模板也明确专门化,否则您无法明确地专门化成员模板。

所以只有这样的东西才能起作用:

template<> template<>
void Test<int>::doSomething<int>()
{
}

答案 2 :(得分:1)

你总是可以使函数内联

template <class T>
class Test
{
public:
 template <class Z>
 void doSomething() { cout << "default" << endl; }

 template<>
 void doSomething<int>() { cout << "int" << endl;}
 template<>
 void doSomething<double>() { cout << "double" << endl; }
private:
 T obj;
};

答案 3 :(得分:0)

我觉得这个很挑剔。我想你不能这样做,请阅读this

答案 4 :(得分:0)

不确定这是否是g ++中的错误,但这会编译并生成我期望的内容。

#include<typeinfo>
#include<iostream>

template<typename T>
class Test
{
public:
    template<typename Z>
    void doSomething();

private:
    T obj;
};

template<typename T>
template<typename Z>
void Test<T>::doSomething()
{
    Z val;
    std::cout << __func__ << ": type " << typeid(val).name() << std::endl;
}

int main(int argc, char *argv[])
{
    Test<double> a;
    a.doSomething<int>();
    a.doSomething<double>();
}

答案 5 :(得分:-2)

icecrime发布了一个临时答案,由于Visual C ++ 2008可能存在一些错误而被编译:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};
template <>
template <typename T>
void Test<T>::doSomething<int>(){
 //do something
}

检查他目前的答案。 至少在VC ++ 2008中有趣的事情是,在专门使用内联定义时没有问题编译,但是对于具有非内联定义的特化,一旦有多个版本就无法成功编译。