Почему стандарт C ++ не запрещает такое ужасное использование? - PullRequest
3 голосов
/ 01 декабря 2010

Исходный код очень прост и очевиден.Вопрос включен в комментарий.

#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;
}

Ответы [ 2 ]

7 голосов
/ 01 декабря 2010

Прежде всего, существует третий вариант вашего кода:

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

Теперь, почему параметры по умолчанию копируются?Я предполагаю, но это просто дикое предположение, что считается предпочтительным, чтобы поведение bind по умолчанию не зависело от времени жизни параметров: результатом привязки является функтор, вызов которого может быть отложен на долгое время после уничтожения параметров.

Вы ожидаете, что следующий код даст UB по умолчанию ?

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

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

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

    f(); // Boom ?
}
0 голосов
/ 01 декабря 2010

Задача C ++ не состоит в том, чтобы сделать невозможным или даже трудным написание медленного кода. Это просто требует от вас явного запроса колокольчиков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...