在这段代码中调用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 :: binder2nd&lt; _Fn2&gt; :: operator()(const 的std ::矢量&lt;&_Ty GT; &amp;)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.
答案 0 :(得分:6)
这种行为定义明确(每个正确的C ++编译器都无法编译代码)。
在课程模板D.9.3
的标准(N3376)部分binder2nd
中,存在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&
,那么它们就会发生冲突。
答案 1 :(得分: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>
中的先前组件强得多。