将 bind1st 用于通过引用获取参数的方法
Posted
技术标签:
【中文标题】将 bind1st 用于通过引用获取参数的方法【英文标题】:Using bind1st for a method that takes argument by reference 【发布时间】:2011-10-19 14:14:28 【问题描述】:我有一个这样的结构:
struct A
void i(int i)
void s(string const &s)
;
现在当我尝试这个时:
bind1st(mem_fun(&A::i), &a)(0);
bind1st(mem_fun(&A::s), &a)("");
第一行编译OK,第二行报错:
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(299): error C2535: 'void std::binder1st<_Fn2>::operator ()(const std::basic_string<_Elem,_Traits,_Ax> &) const' : member function already defined or declared
with
[
_Fn2=std::mem_fun1_t<void,A,const std::string &>,
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(293) : see declaration of 'std::binder1st<_Fn2>::operator ()'
with
[
_Fn2=std::mem_fun1_t<void,A,const std::string &>
]
c:\work\sources\exception\test\exception\main.cpp(33) : see reference to class template instantiation 'std::binder1st<_Fn2>' being compiled
with
[
_Fn2=std::mem_fun1_t<void,A,const std::string &>
]
可能是什么问题?我该如何解决?
编辑:
似乎任何引用参数都是一个问题。因此,如果我将 i
方法更改为 void i(int &i)
我会收到类似的错误。
【问题讨论】:
鉴于我们是在 2011 年并且拥有 C++11,您可能想看看 C++11sstd::bind
或 boost::bind
,它们使这些数量级的事情更容易处理。
@PlasmaHH:不幸的是,我不能在这个项目中使用 C++11。
【参考方案1】:
std::bind1st 和 std::bind2nd 不接受接受引用参数的函子,因为它们本身形成对这些参数的引用。你可以
-
对函数输入使用指针而不是引用
使用 boost::bind
接受复制字符串的性能成本
【讨论】:
【参考方案2】:问题是库规范中的缺陷。
看看这个针对 gcc 的错误报告以及由此产生的讨论:Bug 37811 - bind1st fails on mem_fun with reference argument
C++03 缺乏构建完美绑定库的工具。此问题已在 C++11 中通过完美转发和 std::bind 修复。
【讨论】:
【参考方案3】:看看这个post对模板参数的要求进行了解释。 正如您已经假设对 std::string 的引用是问题所在。这不是一个有效的模板参数。
【讨论】:
虽然这是真的,但函数的参数类型通过 first_argument_type typedef 从 mem_fun 传输到 bind1st,并且引用是有效的 typedef。所以 std::bind1st 可以理论上接受引用,但实现方式不同(并且此实现是由标准 IIRC 强制执行的)。【参考方案4】:通过指针改变引用
#include <functional>
#include <string>
struct A
void i(int i)
void s(const std::string *s)
;
int main(void)
A a;
std::bind1st(std::mem_fun(&A::i), &a)(0);
const std::string s("");
std::bind1st(std::mem_fun(&A::s), &a)(&s);
【讨论】:
以上是关于将 bind1st 用于通过引用获取参数的方法的主要内容,如果未能解决你的问题,请参考以下文章