【问题标题】:tr1::mem_fn and members with default argumentstr1::mem_fn 和具有默认参数的成员
【发布时间】:2008-11-16 19:25:24
【问题描述】:

我的类有一个带有默认参数的成员函数。

struct Class
{
    void member(int n = 0)
    {}
};

通过 std::tr1::mem_fn 我可以调用它:

Class object;

std::tr1::mem_fn(&Class::member)(object,10);

也就是说,如果我想使用默认参数调用对象上的 callable 成员,正确的语法是什么?

std::tr1::mem_fn(&Class::member)(object); // This does not work

g++ 报错如下:

test.cc:17: error: no match for call to ‘(std::tr1::_Mem_fn<void (Class::*)(int)>) (Class&)’
/usr/include/c++/4.3/tr1_impl/functional:551: note: candidates are: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class&, _ArgTypes ...) const [with _Res = void, _Class = Class, _ArgTypes = int]
/usr/include/c++/4.3/tr1_impl/functional:556: note:                 _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class*, _ArgTypes ...) const [with _Res = void, _Class = Class, _ArgTypes = int]

当 Class::member 被采用不同参数的成员重载时,我仍然遇到同样的问题......

【问题讨论】:

    标签: c++ tr1


    【解决方案1】:

    默认函数在调用时绑定,但不能隐式绑定到任何类型的包装器中,因为它们的实现方式。当你传递&amp;Class::member 时,mem_fn 只看到一个void (Class::*)(int),而看不到默认参数。使用tr1::bind,您可以显式绑定默认参数:std::tr1::bind(&amp;Class::member, 0),或者您可以像使用mem_fn 一样使用它,但您不能在一个对象中同时执行这两种操作。您必须为此编写自己的包装类。

    至于重载,您必须显式指定mem_fn 的模板参数,以便像mem_fn&lt;void(int)&gt;(&amp;Class::member) 一样选择正确的函数指针。

    【讨论】:

      【解决方案2】:

      原因是任何默认参数都不会改变函数的函数类型。

      mem_fn 无法知道函数只需要 1 个参数,或者函数的第二个参数是可选的,因为它获得的所有知识都是由 &amp;Class::member 的类型提供给它的(它仍然是 @987654323 @) 。因此,它需要一个整数作为第二个参数。

      如果要重载传递成员函数的地址,则必须强制转换为正确的成员函数指针类型:

      static_cast&lt;void(Class::*)()&gt;(&amp;Class::member) 而不仅仅是&amp;Class::member,因此编译器有一个上下文来确定要采用哪个地址。

      编辑:coppro 有一个更好的解决方案如何提供上下文:std::tr1::mem_fn&lt;void()&gt;(&amp;Class::member)

      【讨论】:

        猜你喜欢
        • 2018-06-16
        • 1970-01-01
        • 2019-12-23
        • 2010-09-23
        • 2016-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-08
        相关资源
        最近更新 更多