8

func()私は最近、このコードを呼び出すときにエラーメッセージを理解するのにかなりの時間を費やしました。

int main()
{
    vector< vector<double> > v;

    double sum = 0;
    for_each( v.begin(), v.end(), 
        bind2nd( ptr_fun(func), &sum ) );

    return 0;
}

そのように宣言されたときfunc()、コードは正常にコンパイルされました:

void func( vector<double> v, double *sum )
{
}

この宣言を(効率のために)使用すると、コンパイラエラーが発生しました:

void func( const vector<double> &v, double *sum )
{
}

私が予想したエラーは、binder2ndのoperator()の定義のために、参照から参照へのエラーのようなものでした。

result_type operator()(const argument_type& _Left) const

代わりに、驚いたことに、Visual C ++(VS2012)コンパイラによって発生したエラーは次のとおりです。

エラーC2535:'void std :: binary2nd <_Fn2> :: operator()(const std :: vector <_Ty>&)const':メンバー関数はすでに定義または宣言されています

解読できません。

  • どのメカニズムoperator()すでに定義されているか説明できますか?

私が得た完全なエラーは次のとおりです。

error C2535: 'void std::binder2nd<_Fn2>::operator ()(const std::vector<_Ty> &) const' : member function already defined or declared
with
[
     _Fn2=std::pointer_to_binary_function<const std::vector<double> &,double *,void,void (__cdecl *)(const std::vector<double> &,double *)>,
      _Ty=double
]
c:\vc\include\xfunctional(319) : see declaration of 'std::binder2nd<_Fn2>::operator ()' 
with
[
      _Fn2=std::pointer_to_binary_function<const std::vector<double> &,double *,void,void (__cdecl *)(const std::vector<double> &,double *)>
] 
c:\consoleapplication1.cpp(31) : see reference to class template instantiation 'std::binder2nd<_Fn2>' being compiled 
with 
[
       _Fn2=std::pointer_to_binary_function<const std::vector<double> &,double *,void,void (__cdecl *)(const std::vector<double> &,double *)>
]

Build FAILED.
4

2 に答える 2

6

この動作は明確に定義されています(正しいC ++コンパイラはすべてコードのコンパイルに失敗します)。

D.9.3クラステンプレートの標準(N3376)セクションからbinder2nd、次の2つの定義がoperator()存在します。

typename Fn::result_type
operator()(const typename Fn::first_argument_type& x) const;

typename Fn::result_type
operator()(typename Fn::first_argument_type& x) const;

first_argument_typeがすでにの場合const T&、それらは競合します。

于 2012-09-10T11:18:36.787 に答える
0

これは答えではありませんが、最新のC ++ 11ソリューションを記録したいだけです。このソリューションでは、すべての小さなバインドヘルパーが非推奨になり、ユニバーサルが優先されますstd::bind

#include <functional>
#include <vector>
#include <algorithm>

void func(std::vector<double> const & v, double * sum) { /* ... */ }

int main()
{
    std::vector<std::vector<double>> v;
    double sum = 0;
    std::for_each(v.begin(), v.end(), std::bind(func, std::placeholders::_1, &sum));
}

C ++ 11の可変個引数テンプレート、および型変更特性のより包括的なコレクションはstd::bind、の以前のコンポーネントよりもはるかに強力な推論能力を提供し<functional>ます。

于 2012-09-10T11:02:12.477 に答える