0

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);
      }  
4

3 に答える 3

2

表示を簡単にするために、タイプをに置き換えましPointdouble。以下のコードは私の主張を理解するのに十分なはずです:

// 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のコンストラクターに転送するだけのファクトリ関数であるため、ユニバーサル参照と完全な転送を使用する必要があります。コードは次のようになります。

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)...);
}
于 2013-03-24T18:58:35.727 に答える
1

http://en.wikipedia.org/wiki/Variadic_template(可変個引数テンプレート)について読むことができます。

または、次のようなデフォルトのパラメータをテンプレートに指定できます。

template< typename F1, typename F2 = void, typename F3 = void>  

どちらもVisualStudio2012にはまだ実装されていませんが、何を使用しているかわからない

または(そしてあなたはそれが気に入らないかもしれません)あなたのクラス(異なる名前..)とテンプレートをそれぞれ1、2、3つのパラメーターの上に複製します...

于 2013-03-24T18:22:59.220 に答える
1

タプルと一緒に可変個引数テンプレートを使用できます。

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...
于 2013-03-24T18:48:34.237 に答える