我有一个由一些模板参数参数化的类:
template<typename Scalar, typename Integrator, int Dimension>
class foo;
每个模板参数都可以是几种可能的类型之一。目前使用的 foo 类型是在 man 中硬编码的 typedef foo<...> foo_type
.我希望调整我的程序,以便收集 foo
的得到支持;像这样的东西:
if (desired_foo_str == "2DSimpleFloat")
{
foo<float,Simple,2>(params).method();
}
else if (desired_foo_str == "3DSimpleDouble")
{
foo<double,Simple,3>(params).method();
}
else
{
std::cout << "Unsupported foo."
}
foo 的接口(interface)不依赖于它的模板参数。我的问题是如何改进此解决方案?我知道boost::mpl
提供了一个类型 vector ,但它似乎更多的是为了减少编译时间而不是运行时切换。
澄清
假设(这是一个简化)我的程序在 N 维(由用户提供)中获取一组点并将它们集成。 SIMD 可以加速维度、积分方法和标量类型的某些组合(因此使用模板参数)。 foo<A,B,N>
的所有组合是有效的,但是不同的用户(他们都编译了我的程序)将只需要几个特定的特化来完成他们的工作。我希望允许:
$ integrate --method=2DSimpleFloat mypoints2d.dat
$ integrate --methid=3DSimpleDouble mypoints3d.dat
所以运行时选择他们希望使用的方法。我想知道哪种框架最能让我将类型与字符串相关联,以便我可以更好地处理上述情况。
最佳答案
您可以制作会抛出错误的模板化默认方法,以及您支持的每个组合的模板特化。
class Simple {};
template<typename Scalar, typename Integrator, int Dimension>
class foo
{
public:
void method();
foo() {}
};
// default implementation throws an error
template<typename Scalar, typename Integrator, int Dimension>
void foo<Scalar,Integrator,Dimension>::method() { cout << "unsupported\n"; };
// override default for supported cases:-
template<>
void foo<double,Simple,2>::method() { cout <<"method1\n"; };
template<>
void foo<double,Simple,3>::method() { cout <<"method2\n"; };
// test program
void main() {
foo<float,Simple,2> a; a.method(); // output "unsupported"
foo<double,Simple,2> b; b.method(); // output "method1"
foo<double,Simple,3> c; c.method(); // output "method2"
}
您应该能够在整个类(class)中自由混合通用实现和特殊用途重写; (例如,也许一些渗透可以用 SIMD 内在函数或其他任何东西来处理)
如果所有的类方法都是相同的和通用的,限制使用的一个方便的方法可能是限制构造函数,这样不需要的情况就不能被实例化
一般来说,如果正确使用重载和模板机制,您应该能够避免在使用它们的地方手动检查类型。 这可以在没有任何指针或虚拟分派(dispatch)的情况下静态链接所有编译时间。
如果支持的实现相同,覆盖可以是包装器以指向另一个模板化方法,如上文所建议的。
关于C++ 在运行时查找类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8282443/