Frage

Der folgende Code kompiliert nicht in Visual C ++ 2005.

class SomeClass {
public: boost::function<void()> func;
        SomeClass(boost::function<void()> &func): func(func) { }
};

void someFunc() {
    std::cout << "someFunc" << std::endl;
}

int main() {
    SomeClass sc(boost::function<void()>(&someFunc));
    sc.func(); // error C2228: left of '.func' must have class/struct/union
    return 0;
}

Wenn ich Klammern um das Argument für den Konstruktor setzen oder Someclass konstruiert die boost :: Funktionsobjekt außerhalb der Argumentliste kompiliert es in Ordnung.

    SomeClass sc((boost::function<void()>(&someFunc)));
    // or
    boost::function<void()> f(&someFunc);
    SomeClass sc(f);

Was ist das Problem mit dem vorherigen Code?

War es hilfreich?

Lösung

Es ist eine Funktionsdeklaration für eine Funktion einen Verweis auf einen boost:function <void()> nehmen und eine SomeClass zurück. Sie können die folgende Regel merken, was viele andere solche Begriffsklärung Fälle anzuwenden ausfällt. Sie können Beschreibungen dieser Fälle in Abschnitt 8.2 der C ++ Standard-finden.

  

Jedes Konstrukt, das möglicherweise eine Erklärung als Erklärung zur Kenntnis genommen werden könnte

Das heißt, wird im Folgenden als Parameter Erklärung zur Kenntnis genommen werden, mit überflüssigen Klammern

boost::function<void()>(&someFunc)

Wenn Sie die Klammern entfernen, wird dies deutlich geworden,

boost::function<void()> &someFunc

Und so wird die ganze Erklärung nicht mehr ein Objekt deklariert, sondern eine Funktion

SomeClass sc(boost::function<void()> &someFunc);

Um es zu beheben, verwenden Sie die Guss Notation

SomeClass sc((boost::function<void()>)&someFunc);

oder setzen Sie Klammern um den gesamten Ausdruck, wie Sie getan haben.

Hier ist der Standard in seiner ganzen Pracht von 8.2:

  

Die Mehrdeutigkeit von der Ähnlichkeit zwischen einer funktions Casts und einer Erklärung in 6.8 erwähnt entsteht auch im Rahmen einer Erklärung erfolgen kann. In diesem Zusammenhang ist die Wahl zwischen einer Funktionsdeklaration mit einem redundanten Satz von Klammern um einen Parameternamen und eine Objektdeklaration mit einem funktions Casts als Initialisierer. Ebenso wie bei den erwähnten Zweideutigkeiten in 6.8 ist die Auflösung jedes Konstrukt zu berücksichtigen, die möglicherweise eine Erklärung einer Erklärung sein könnten. [Anmerkung: Eine Erklärung kann explizit von einem Nicht-Funktion-Casts vereindeutigt werden, indem man a = Initialisierung, um anzuzeigen, oder durch die redundanten Klammern um die Parameternamen zu entfernen. ]

Beachten Sie, dass Vorrang für die Steuerung, darf sie Klammern einführte fast überall, wie in dem folgenden

int (((((((a))))))) = 3;
int (*(pa)) = &a;

Andere Tipps

Dies wird als "C ++" s drängendsten Parse"(von ein Buch von Scott Meyers genannt Effective STL ).

Wie beantwortet oben , zieht der Compiler die problematische Zeile als Funktionsdeklaration zu interpretieren.

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