为什么 C++标准不禁止这种可怕的用法吗?

发布于 2024-10-05 04:35:42 字数 996 浏览 8 评论 0原文

源代码非常简单,不言而喻。该问题包含在评论中。

#include <iostream>
#include <functional>

using namespace std;
using namespace std::tr1;

struct A
{
    A()
    {
        cout << "A::ctor" << endl;
    }

    ~A()
    {
        cout << "A::dtor" << endl;
    }

    void foo()
    {}
};

int main()
{
    A a;
    /*
    Performance penalty!!!

    The following line will implicitly call A::dtor SIX times!!! (VC++ 2010)    
    */
    bind(&A::foo, a)();  

    /*
    The following line doesn't call A::dtor.

    It is obvious that: when binding a member function, passing a pointer as its first 
    argument is (almost) always the best way. 

    Now, the problem is: 

    Why does the C++ standard not prohibit bind(&SomeClass::SomeMemberFunc, arg1, ...) 
    from taking arg1 by value? If so, the above bind(&A::foo, a)(); wouldn't be
    compiled, which is just we want.
    */
    bind(&A::foo, &a)(); 

    return 0;
}

The source code is very simple and self-evident. The question is included in the comment.

#include <iostream>
#include <functional>

using namespace std;
using namespace std::tr1;

struct A
{
    A()
    {
        cout << "A::ctor" << endl;
    }

    ~A()
    {
        cout << "A::dtor" << endl;
    }

    void foo()
    {}
};

int main()
{
    A a;
    /*
    Performance penalty!!!

    The following line will implicitly call A::dtor SIX times!!! (VC++ 2010)    
    */
    bind(&A::foo, a)();  

    /*
    The following line doesn't call A::dtor.

    It is obvious that: when binding a member function, passing a pointer as its first 
    argument is (almost) always the best way. 

    Now, the problem is: 

    Why does the C++ standard not prohibit bind(&SomeClass::SomeMemberFunc, arg1, ...) 
    from taking arg1 by value? If so, the above bind(&A::foo, a)(); wouldn't be
    compiled, which is just we want.
    */
    bind(&A::foo, &a)(); 

    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光暖心i 2024-10-12 04:35:42

首先,您的代码还有第三种替代方案:

bind(&A::foo, std::ref(a))(); 

现在,为什么默认情况下通过复制获取参数?我认为,但这只是一个疯狂的猜测,认为绑定默认行为独立于参数生命周期被认为是更可取的:绑定的结果是一个函子,其调用可能会延迟很长时间参数破坏。

您期望以下代码默认生成 UB 吗?

void foo(int i) { /* ... */ }

int main()
{
    std::function<void ()> f;

    {
        int i = 0;
        f = std::bind(foo, i);
    }

    f(); // Boom ?
}

First of all, there is a third alternative to your code :

bind(&A::foo, std::ref(a))(); 

Now, why are parameters taken by copy by default ? I presume, but it's just a wild guess, that it is considered preferable for bind default behavior to be independent of the parameters lifetime : the result of a bind is a functor of which invocation could be delayed long after parameters destruction.

Would you expect from the following code to yield UB by default ?

void foo(int i) { /* ... */ }

int main()
{
    std::function<void ()> f;

    {
        int i = 0;
        f = std::bind(foo, i);
    }

    f(); // Boom ?
}
人间☆小暴躁 2024-10-12 04:35:42

C++ 的使命并不是让编写缓慢的代码成为不可能,甚至变得更加困难。它只是要求您明确要求附加功能。

The mandate of C++ is not to make it impossible, or even harder, to write slow code. It is merely to require you to request the bells and whistles explicitly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文