6

是否可以进行以下设计?:

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':模板参数太少。

4

6 回答 6

6

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

从 14.7.3/18 开始:

在类模板的成员或出现在命名空间范围内的成员模板的显式特化声明中,成员模板和它的一些封闭类模板可能保持未特化,除非声明不应显式特化类成员模板,如果它封闭类模板也没有明确专门化

于 2010-11-25T08:08:37.177 回答
2

您不能显式特化成员模板,除非它的封闭类模板也显式特化。

所以只有这样的事情才会起作用:

template<> template<>
void Test<int>::doSomething<int>()
{
}
于 2010-11-25T08:17:18.460 回答
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;
};
于 2010-11-25T08:28:35.480 回答
0

我觉得这个很挑剔。我想你做不到,读这个

于 2010-11-25T08:22:52.593 回答
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>();
}
于 2010-11-25T14:33:12.127 回答
-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 来说有趣的是,在专门使用内联定义时编译没有问题,但是对于具有非内联定义的专门化,一旦有多个版本,它就不会成功编译。

于 2010-11-25T08:23:04.880 回答