tr1::mem_fn 和 tr1::bind:关于常量正确性和重载

Nic*_*lli 5 c++ functional-programming tr1 c++11

以下代码段有什么问题?

#include <tr1/functional>
#include <functional>
#include <iostream>

using namespace std::tr1::placeholders;

struct abc
{
    typedef void result_type;

    void hello(int)
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    void hello(int) const
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    abc()
    {}
};

int
main(int argc, char *argv[])
{
    const abc x;
    int a = 1;

    std::tr1::bind(&abc::hello, x , _1)(a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

尝试用 g++-4.3 编译它,似乎cv -qualifier 重载函数混淆了两者tr1::mem_fn<>tr1::bind<>并出现以下错误:

no matching function for call to ‘bind(<unresolved overloaded function type>,...
Run Code Online (Sandbox Code Playgroud)

相反,以下代码段可以编译,但似乎破坏了const-correctness

struct abc
{
    typedef void result_type;

    void operator()(int)
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    void operator()(int) const
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    abc()
    {}
};

...

    const abc x;
    int a = 1;
    std::tr1::bind( x , _1)(a);
Run Code Online (Sandbox Code Playgroud)

有什么线索吗?

Joh*_*nck 4

this查找是在不知道 的常量时完成的。你只需要通过强制转换给它一个提示。尝试这个:

typedef void (abc::*fptr)(int) const; // or remove const
std::tr1::bind((fptr)&abc::hello, x , _1)(a);
Run Code Online (Sandbox Code Playgroud)

您可能还注意到,删除const静止图像是有效的。这是因为您应该通过指针传递 x(因为 C++ 成员函数的第一个参数(隐式this参数)始终是指针)。试试这个:

typedef void (abc::*fptr)(int) const; // won't compile without const (good!)
std::tr1::bind((fptr)&abc::hello, &x , _1)(a);
Run Code Online (Sandbox Code Playgroud)

正如我在下面的评论中发现的那样,如果您&像最初那样省略了 ,您将按传递 x ,这通常不是您想要的(尽管它在您的特定示例中几乎没有实际区别)。这实际上似乎是一个不幸的陷阱bind