mac*_*low 3 c++ templates template-specialization
我有一个模板
template <int a, int b>
class MyTemplateClass
{
// ....
void computeSomething();
};
Run Code Online (Sandbox Code Playgroud)
我想部分专注于 b 的两个特殊情况:
template<int a>
void MyTemplateClass<a, 2> :: computeSomething()
{
// Special case for b=2 here
}
template<int a>
void MyTemplateClass<a, 3> :: computeSomething()
{
// Special case for b=3 here
}
Run Code Online (Sandbox Code Playgroud)
但是,据我所知,部分特化对于成员函数是无效的。我怎样才能实现我想要的?还有其他解决方案吗?谢谢!
一种可能的方法是 estract compute()
,仅为它创建一个基类并专门化这个基类。
我的意思是...如果你创建一个通用版本和两个专业化 fooSub
template <int a, int b>
struct fooSub
{
void compute ()
{ std::cout << "- foo generic compute()" << std::endl; }
};
template <int a>
struct fooSub<a, 2>
{
void compute ()
{ std::cout << "- foo compute() for 2" << std::endl; }
};
template <int a>
struct fooSub<a, 3>
{
void compute ()
{ std::cout << "- foo compute() for 3" << std::endl; }
};
Run Code Online (Sandbox Code Playgroud)
您可以foo
通过继承“专门化”计算,如下所示
template <int a, int b>
struct foo : public fooSub<a, b>
{ };
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案,如果可以使用至少C ++ 11,是激活/取消激活不同版本的compute()
使用SFINAE( std::enable_if
)如下面的bar
类
template <int a, int b>
struct bar
{
template <int bb = b>
typename std::enable_if<(b == bb) && (b != 2) && (b != 3)>::type
compute ()
{ std::cout << "- bar generic compute()" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 2)>::type compute ()
{ std::cout << "- bar compute() for 2" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 3)>::type compute ()
{ std::cout << "- bar compute() for 3" << std::endl; }
};
Run Code Online (Sandbox Code Playgroud)
遵循两种方式的完整可编译示例
#include <iostream>
#include <type_traits>
template <int a, int b>
struct fooSub
{
void compute ()
{ std::cout << "- foo generic compute()" << std::endl; }
};
template <int a>
struct fooSub<a, 2>
{
void compute ()
{ std::cout << "- foo compute() for 2" << std::endl; }
};
template <int a>
struct fooSub<a, 3>
{
void compute ()
{ std::cout << "- foo compute() for 3" << std::endl; }
};
template <int a, int b>
struct foo : public fooSub<a, b>
{ };
template <int a, int b>
struct bar
{
template <int bb = b>
typename std::enable_if<(b == bb) && (b != 2) && (b != 3)>::type
compute ()
{ std::cout << "- bar generic compute()" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 2)>::type compute ()
{ std::cout << "- bar compute() for 2" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 3)>::type compute ()
{ std::cout << "- bar compute() for 3" << std::endl; }
};
int main()
{
foo<0, 1>{}.compute(); // print - foo generic compute()
foo<1, 2>{}.compute(); // print - foo compute() for 2
foo<2, 3>{}.compute(); // print - foo compute() for 3
bar<2, 1>{}.compute(); // print - bar generic compute()
bar<3, 2>{}.compute(); // print - bar compute() for 2
bar<4, 3>{}.compute(); // print - bar compute() for 3
}
Run Code Online (Sandbox Code Playgroud)