一种可能的方式是提取
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; }
};
您可以通过继承简单地将计算“专门化”到foo
中,方法如下:
template <int a, int b>
struct foo : public fooSub<a, b>
{ };
如果您使用至少C++11,另一个可能的解决方案是通过以下
bar
类中的SFINAE(
std::enable_if
)激活/停用不同版本的
compute()
。
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; }
};
以下是两种方式的完整可编译示例。
#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();
foo<1, 2>{}.compute();
foo<2, 3>{}.compute();
bar<2, 1>{}.compute();
bar<3, 2>{}.compute();
bar<4, 3>{}.compute();
}