Frage

Der Quellcode ist sehr einfach und selbstverständlich. Die Frage ist im Kommentar enthalten.

#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;
}
War es hilfreich?

Lösung

Zunächst einmal gibt es eine dritte Alternative zu Ihrem Code:

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

Nun, warum sind Parameter, die von Kopie standardmäßig genommen? Ich nehme an, aber es ist nur eine wilde Vermutung, dass es für bind Standardverhalten bevorzugt betrachtet wird, unabhängig von den Parametern Lebensdauer zu sein: das Ergebnis einer Bindung ist ein Funktor von dem Aufruf lange nach Parameter Zerstörung verzögert werden könnte

.

Sie erwarten würde, von dem folgenden Code UB standardmäßig erhalten

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

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

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

    f(); // Boom ?
}

Andere Tipps

Das Mandat von C ++ ist es nicht unmöglich zu machen, oder noch härter, langsam Code zu schreiben. Es ist lediglich die Sie benötigen, um die Glocken und Trillerpfeifen explizit anfordern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top