我有一个类结构
template<int T>
class MyClass {
public:
MyClass(){};
~MyClass(){};
template<class K> void foo();
};
现在我想根据foo()
中使用的整数值来专门化MyClass<int>
方法,例如,如果我们拥有MyClass<2>
的代码,我想使用不同的版本如果我有foo<K>()
,则为MyClass<3>
。不过,我希望foo<K>()
上的K
仍然未经专业化。
所以这意味着这样的事情就可以了
MyClass<2> myc2;
MyClass<3> myc3;
myc2.foo<SomeClass>();
myc2.foo<SomeOtherClass>();
myc3.foo<SomeClass>();
myc3.foo<SomeOtherClass>();
是否有可能以这种方式专攻但不专注于K
?我尝试了几种组合但没有成功。
答案 0 :(得分:2)
如果我理解你的问题,这就是你想要的:
template<int T>
class MyClass {
public:
MyClass(){};
~MyClass(){};
template<class K> void foo();
};
template<int T>
template<class K>
void MyClass<T>::foo()
{
std::cout << "general form\n";
}
template<>
template<class K>
void MyClass<2>::foo()
{
std::cout << "MyClass<2>\n";
}
int main()
{
MyClass<3> c1;
c1.foo<int>(); // general form
MyClass<2> c2;
c2.foo<int>(); // MyClass<2>
c2.foo<float>(); // MyClass<2>
}
答案 1 :(得分:1)
您可以尝试使用boost :: enable_if,它允许启用或禁用类和方法的特定特化。看一下这里的示例:http://www.boost.org/doc/libs/1_48_0/libs/utility/enable_if.html
答案 2 :(得分:1)
这适用于我的Visual C ++ 2010:
template<int T>
class MyClass {
public:
MyClass(){};
~MyClass(){};
template<class K> void foo() {
std::cout << "foo() for T" << std::endl;
}
};
template<>
template<class K>
void MyClass<2>::foo() {
std::cout << "foo() for 2" << std::endl;
}
template<>
template<class K>
void MyClass<3>::foo() {
std::cout << "foo() for 3" << std::endl;
}
void main() {
MyClass<1>().foo<int>();
MyClass<2>().foo<float>();
MyClass<3>().foo<std::string>();
}
打印:
foo() for T
foo() for 2
foo() for 3
答案 3 :(得分:-1)
不专业。只需将对重载函数的调用委托为:
template<int T>
class MyClass {
public:
MyClass(){};
~MyClass(){};
template<class K>
void foo()
{
foo_worker(static_cast<K*>(0)); //delegate to overloaded function
}
private:
template<class K>
void foo_worker(K*)
{
//general code goes here
}
void foo_worker(SomeClass*)
{
//code when K = SomeClass
}
void foo_worker(SomeOtherClass*)
{
//code when K = SomeOtherClass
}
};
以下是它的工作原理:
K
为SomeClass
,则最终会调用foo_worker(SomeClass*)
。K
为SomeOtherClass
,则会调用foo_worker(SomeOtherClass*)
。foo_worker
。注意foo_worker
中的参数用于使编译器能够选择正确的重载函数。
答案 4 :(得分:-1)
问题通常是模板类的特殊化,需要专门化整个类,如果类具有大的接口则不方便。一种方法是提供另一个间接级别,如下所示:
#include <iostream>
template<int T>
class MyClass {
public:
MyClass(){};
~MyClass(){};
class fooImpl;
template<class K> void foo()
{
fooImpl::fn<K>();
}
};
template<>
class MyClass<2>::fooImpl
{
public:
template <class K> static void fn()
{
std::cout << "two : " << typeid(K).name() << "\n";
}
};
template<>
class MyClass<3>::fooImpl
{
public:
template <class K> static void fn()
{
std::cout << "three : " << typeid(K).name() << "\n";
}
};
class SomeClass {};
class SomeOtherClass {};
int main()
{
MyClass<2> myc2;
MyClass<3> myc3;
myc2.foo<SomeClass>();
myc2.foo<SomeOtherClass>();
myc3.foo<SomeClass>();
myc3.foo<SomeOtherClass>();
return 0;
}
然后你只需要专门化foo(fooImpl)的实现类,而不是你想要添加的MyClass上的所有其他成员函数。
我的编译器提供了以下输出:
two : class SomeClass
two : class SomeOtherClass
three : class SomeClass
three : class SomeOtherClass