c++ - 我应该如何重载模板化结构?

标签 c++ templates struct overloading

我希望编写一个可以接受 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);
      }  

最佳答案

为了简化演示,我将类型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)...);
}

关于c++ - 我应该如何重载模板化结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15602120/

相关文章:

c++ - 函数模板参数的顺序

c - 查找结构数组中的记录数

c - 不兼容的指针类型警告

c++ - 模板类中不可复制的静态常量成员类

c++ - 设置子模块目标的输出目录时 CMAKE_BINARY_DIR 和 PROJECT_BINARY_DIR 之间的权衡

c++ - 从 vector 私有(private)继承,公开相等运算符

c++ - 函数的 std::vector

c++ - 如何在不与标准库运算符冲突的情况下为一组相关类模板重载运算符?

c - 创建匿名结构的 typedef 有什么意义?

c++ - 使用字符串类型的键存储散列值的最佳结构