将 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 &amp;i) 我会收到类似的错误。

【问题讨论】:

鉴于我们是在 2011 年并且拥有 C++11,您可能想看看 C++11s std::bindboost::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 用于通过引用获取参数的方法的主要内容,如果未能解决你的问题,请参考以下文章

类型不匹配解决了通过引用获取参数的闭包

not1,not2,bind1st,bind2nd

C#获取类以及类下的方法(用于Asp.Net MVC)

Angular:如何从 httpClient 请求中获取参数并用于循环相同的请求

是否可以获取对象引用计数?

Java 获取Excel分页坐标位置(单元格)