C++ 模板类专门化的模板方法
这是我的密码:C++ 模板类专门化的模板方法,c++,linux,templates,g++,C++,Linux,Templates,G++,这是我的密码: template<typename T1, typename T2> class MyClass { public: template<int num> static int DoSomething(); }; template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething() { cout &l
template<typename T1, typename T2> class MyClass
{
public:
template<int num> static int DoSomething();
};
template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething()
{
cout << "This is the common method" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
模板类MyClass
{
公众:
模板静态int DoSomething();
};
模板int MyClass::DoSomething()
{
cout这是悲哀但真实的:除非类模板的封闭类模板也被显式专门化,否则不能显式专门化类模板。有关详细信息,请阅读
- 此COMP.Lang.c++。主持线程
- 或本文:
下面我先专门介绍了我的课程,一切都完成了
#include <iostream>
using namespace std;
template<typename T1, typename T2> class MyClass
{
public:
template<int num> static int DoSomething();
};
template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething()
{
cout << "This is the common method" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
template<> template<> int MyClass<char, int>::DoSomething<0>()
{
cout << "This is ZERO!!!" << endl;
cout << "sizeof(T1) = " << sizeof(char) << endl;
cout << "sizeof(T2) = " << sizeof(int) << endl;
return 0;
}
int main() {
MyClass<char, int> m;
m.DoSomething<2>();
m.DoSomething<0>();
return 0;
}
尤里卡!这在MSVCPP10上运行得很好
#include <iostream>
using namespace std;
template<typename T1, typename T2> class MyClass
{
public:
template<int num> static int DoSomething();
template<> static int DoSomething<0>() {
cout << "This is ZERO!!!" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return 0;
}
};
template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething()
{
cout << "This is the common method" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
int main() {
MyClass<char, int> m;
m.DoSomething<2>();
m.DoSomething<0>();
return 0;
}
顺便说一句,不要从专门化中返回num;
。它永远不知道num
是什么。不幸的是,如果不专门化外部模板,就无法专门化作为类模板成员的模板:
C++11 14.7.3/16:在出现在命名空间范围中的类模板或成员模板的成员的显式专门化声明中,成员模板及其某些封闭类模板可能保持非专业化,除非声明不应显式专门化类成员模板,如果其封闭类ss模板也没有明确专门化
我认为您最好的选择是将额外的参数添加到MyClass
,然后部分专门化该参数。我知道,这是一个老问题
但是我在当前的项目中偶然发现了同样的问题,并找到了一个解决方法,它至少可以解决模板参数的问题,模板参数不是类型而是值(比如template
)
我的解决方案的实施:
template<class T> template<int num> void Classname<T>::methodname()
{
if (num == 0)
{
//implementation for num == 0
}
else if (num == 1)
{
//implementation for num == 1
}
//more cases...
}
template模板void Classname::methodname()
{
如果(num==0)
{
//num==0的实现
}
else if(num==1)
{
//num==1的实现
}
//更多案例。。。
}
num==constant
将计算为一个常量表达式,因此编译器将优化您的代码,以便为每种情况保留正确的实现
如果我错了,或者有什么东西使这成为一个糟糕的解决方案,请纠正我;)@MikeSeymour好的。但它在MSVCPP 10上是这样的。@DaddyM:MSVC不强制执行一些标准规则。尤其是在模板编程方面,这很糟糕。我总是用MingW编写复杂的模板部分,如果它编译了,然后将其移动到MSVC。MSVC为我提供了一个扩展名n类成员专门化但该示例并不是明确专门化类成员模板,而是专门化函数成员模板。因此,您突出显示的部分不适用,并且句子前面部分给出的权限似乎适用。@AlanStokes:“类成员模板”表示作为类成员的模板-它可以是函数或嵌套类的模板。“成员类模板”具体指作为成员的类模板(根据14.7.3/1中使用的术语)。GCC至少使用了该解释。14.5.2/1建议作为类成员的模板只是一个模板“成员模板”。“类成员模板”似乎不是一个定义的术语。糟糕。但它看起来会澄清这一点以同意你的答案。有人知道这是为什么吗?我发现了一系列解释,只是解释你不能这样做,但没有提到任何合理的解释。
#include <iostream>
using namespace std;
template<typename T1, typename T2> class MyClass
{
public:
template<int num> static int DoSomething();
template<> static int DoSomething<0>() {
cout << "This is ZERO!!!" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return 0;
}
};
template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething()
{
cout << "This is the common method" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
int main() {
MyClass<char, int> m;
m.DoSomething<2>();
m.DoSomething<0>();
return 0;
}
This is the common method
sizeof(T1) = 1
sizeof(T2) = 4
This is ZERO!!!
sizeof(T1) = 1
sizeof(T2) = 4
template<class T> template<int num> void Classname<T>::methodname()
{
if (num == 0)
{
//implementation for num == 0
}
else if (num == 1)
{
//implementation for num == 1
}
//more cases...
}