C ++機能ライブラリを使用すると、テンプレートを正しくインスタンス化できません

c++ functional-programming templates
C ++機能ライブラリを使用すると、テンプレートを正しくインスタンス化できません

私は、ベクトルの長さが変わらない幾何学的な目的のために主に使用するために、固定サイズのベクトルのクラスを作成しようとしています:

template
class FixedVector
{
private:
    T m_rV[n]; // this is the only data member
     public:
              // class function members
              ...
}

これには、互換性のないサイズのベクトルを使用した操作をコンパイラがチェックするという利点があります。

このクラスのoperator *を作成しようとすると問題が発生します(注:メンバーではありません)。 この演算子は、3 * [1,2,3] = [3,6,9]のように、ベクトルにスカラーを掛ける必要があります。

template
FixedVector operator*(const T   &rX, const FixedVector &cV) const
{   typename std::pointer_to_binary_function op=(util::times);
    FixedVector cT(cV, std::bind1st(op, rX));
    return cT;
}

ここで、timesはベクトルのスカラーメンバーの乗算関数です

template
inline T times(const T &t1, const T &t2)
{   return t1*t2;
}

4行目のコンストラクターのコードは

template
FixedVector::FixedVector(const T rV[n], T (*f)(const T &))
{   util::copy(m_rV, rV, n, f);
}

また、pointer_to_binary_functionとbind1stは、ヘッダーのSTL関数です(これを知っている人は既に知っているはずです)。

呼び出すときにVisual Studio 2005で次のコンパイラエラーが発生します。

    util::FixedVector x; 3*x;

:

fixed_vector.hpp(212) : error 2440:
        'initializing' : cannot convert from 'T (__cdecl *)(const T &,const T &)'
         to 'std::pointer_to_binary_function<_Arg1,_Arg2,_Result>'
with
[
       _Arg1=int,
        _Arg2=int,
        _Result=int
    ]
    No constructor could take the source type, or constructor overload resolution was ambiguous
    testproject.cpp(18) : see reference to function template instantiation 'util::FixedVector util::operator *(const T &,const util::FixedVector &)' being compiled
   with
    [
        T=int,
        n=4
    ]
typename std

pointer_to_binary_functionはstd :: pointer_to_binary_functionに正しくインスタンス化されているように見えますが、基本的なシグネチャはまだ残っています: ‘T(__cdecl *)(const T&、const T&)

” ” ‘

—編集後——————————————– ——————–

コンストラクターがパラメーターとして単純な関数を要求する関数:T(*)(const T&t1、const T&t2)、およびSTL機能オブジェクトは受け入れられないことが示されました。 ここのリンクhttp://www.cplusplus.com/reference/algorithm/for_each/[STL for_each]は、修正方法のガイドとして役立ちました。

コンストラクターによって呼び出されるutil

copy関数から変更し始めました。

From:template void copy(T * dst、const T * src、size_t n、T(* f)(const T&))\ {for(; n> 0; n–、dst 、src )\ {* dst = f(* src); }}

なった

    template
void copy(T *dst, const T *src, size_t n, Function f)
{   for (; n>0; n--, dst++, src++)
    {   *dst = (*f)(*src);
}   }

次に、コンストラクター自体がテンプレート化されました。 から:

template
FixedVector::FixedVector(const T rV[n], T (*f)(const T &))
{   util::copy(m_rV, rV, n, f);
}

今です

     template
template
FixedVector::FixedVector(const FixedVector &cV, Function f)
{   util::copy(m_rV, cV.m_rV, n, f);
}

また、テンプレートのインスタンス化パラメーターにいくつかのconstを追加しました。

template
FixedVector operator*(const T   &rX, const FixedVector &cV)
{   typename std::pointer_to_binary_function op(times);
    FixedVector cT(cV, std::bind1st(op, rX));
    return cT;
}

しかし、私はまだ同じエラーを受け取ります(Tがconst Tに置き換えられているだけです。&を追加して参照(const T&)を示すとエラーがトリガーされ、テンプレートにこれに問題があるようです、BoostとTR1は特別なソリューションを作成していますこれに対処するには-http://en.wikipedia.org/wiki/C%2B%2B_Technical_Report_1#Reference_wrapper[Wikipedia TR1 reference wrapper]を参照してください。

エラーの正確な行は次のとおりです。

typename std::pointer_to_binary_function op(times);

だから私はコンストラクターにさえ到達しません。

私はいくつかの余分なアイデアにとても感謝しています。

  2  0


ベストアンサー

あなたの関数 `util

times`には署名があります:

T times(const T&, const T&)

しかし、この行では:

typename std::pointer_to_binary_function op=(util::times);
`std

pointer_to_binary_function`のコンストラクタは以下を期待しています:

T times(T, T)

引数テンプレートパラメータとして `const T&`を使用することでそれを修正できます:

typename std::pointer_to_binary_function op(util::times);

ここで明示的なコンストラクター表記を使用するために `=`を削除したことに注意してください。 少なくとも(私の)GCCでは、割り当て構文はコンパイラによって拒否されます。

カスタムの times`関数とファンクターラッパーの代わりに、乗算を行うバイナリファンクターを作成しているため、 std

multiplies`を直接使用して同じことを実現できます。

std::multiplies op;

” ” ‘

次の行で、

FixedVector cT(cV, std::bind1st(op, rX));

最初の引数として `FixedVector`を、2番目として単項ファンクターをとるコンストラクターを呼び出しています。 これは、投稿したコンストラクタコードと互換性がありません。

template
FixedVector::FixedVector(const T rV[n], T (*f)(const T &))
{   util::copy(m_rV, rV, n, f);
}

これは単純な配列と関数ポインタを受け取るためです。

2


template
FixedVector::FixedVector(const T rV[n], T (*f)(const T &))
{   util::copy(m_rV, rV, n, f);
}

状態を持つ任意の機能オブジェクトから関数ポインターに変換することはできません。その場合でも、ステートレスC 0xラムダのみに変換できます。 Boost、TR1、およびC 0xにあるテンプレート機能オブジェクト、または「関数」のような多態性オブジェクトを使用する必要があります。

それに、これは非常にわかりにくいです。 なぜ通常の乗算​​をしないのですか? このアプローチよりもはるかに簡単です。

1


タイトルとURLをコピーしました