我希望编写一个模板化结构,以便接受2个或3个类型名称。但是,程序会产生错误template<class F1, class F2, class F3>...' cannot be overloaded
。如何纠正?
template< typename F1, typename F2, typename F3> // this shouldn't be right because the compiler expects three typenames, and the program can provide two
struct Force{
F1 force1;
F2 force2;
F3 force3;
Force(F1 f1, F2 f2) : force1(f1), force2(f2) { // construct out of two forces
}
Force(F1 f1, F2 f2, F3 f3) : force1(f1), force2(f2), force3(f3) { // construct out of three forces
}
Point operator()(double t) {
return force1(t) + force2(t);
}
Point operator()(double t) { // this overloading should not be right because it has the same signature as above
return force1(t) + force2(t) + force3(t);
}
};
// this is used by the main program
template< typename F1, typename F2>
Force<F1, F2> make_physics(F1 first, F2 second){
return Force<F1, F2>(first, second);
}
// this is used by the main program
template< typename F1, typename F2, typename F3>
Force<F1, F2, F3> make_physics(F1 first, F2 second, F3 third){
return Force<F1, F2, F3>(first, second, third);
}
答案 0 :(得分:2)
为简化演示,我已将Point
替换为double
。下面的代码应足以说明我的观点:
// This will be the default F3 argument. It's basically a "zero force".
struct zero {
double operator()(double) { return 0.0; }
};
// You only need one struct Force
template< typename F1, typename F2, typename F3 = zero>
struct Force {
F1 force1;
F2 force2;
F3 force3;
Force(F1 f1, F2 f2, F3 f3 = zero()) : force1(f1), force2(f2), force3(f3) { // construct out of three forces
}
double operator()(double t) {
return force1(t) + force2(t) + force3(t);
}
};
// You might provide two make_physics overload for 2D and 3D problems (that's what you want, right?)
template< typename F1, typename F2>
Force<F1, F2> make_physics(F1 first, F2 second){
return Force<F1, F2>(first, second);
}
template< typename F1, typename F2, typename F3>
Force<F1, F2, F3> make_physics(F1 first, F2 second, F3 third){
return Force<F1, F2, F3>(first, second, third);
}
如果您的编译器具有良好的C ++ 11覆盖率,那么您可以使用可变参数模板函数替换make_physics
的重载。此外,由于这是一个工厂函数,只是将其参数转发给Force
的构造函数,因此您应该使用universal references并完善转发。代码应该是:
template< typename F1, typename F2, typename... F3>
Force<F1, F2, F3...> make_physics(F1&& first, F2&& second, F3&&... third){
return Force<F1, F2, F3...>(std::forward<F1>(first), std::forward<F2>(second), std::forward<F3>(third)...);
}
答案 1 :(得分:1)
您可以阅读http://en.wikipedia.org/wiki/Variadic_template(可变参数模板)..
或者您可以提供模板默认参数:
template< typename F1, typename F2 = void, typename F3 = void>
两者尚未在visual studio 2012中实现,但是...不确定您使用的是什么
或(你可能不喜欢) 复制你的班级(不同的名字..) 并模板上面的1,2和3个参数......
答案 2 :(得分:1)
您可以使用variadic templates和tuple:
template<typename... F>
struct Force
{
std::tuple<F...> f;
};
您还可以提供不同的专业化(此方法在C ++ 03中使用):
template<typename F1, typename F2 = void, typename F3 = void>
struct Force
{
F1 a;
F2 b;
F3 c;
};
template<typename F1, typename F2>
struct Force<F1,F2,void>
{
F1 a;
F2 b;
};
// and so on...