2016-03-30 5 views
0

Ich benutze Eigen-Bibliothek in C++ und stieß auf ein seltsames Problem.Explizite Typ-Deklaration Vs automatisch in Eigen-Ausdrücke in C++

Eigen::VectorXd someV(){ 
    Eigen::VectorXd a(3); 
    a(1)=1.2; 
    a(2)=2.3; 
    a(0)=3.2; 
    return a; 
} 

int main(){ 
    auto c=2.*someV(); 
    std::cout<<c; 
    return 0; 
} 

gibt nichts zurück.

int main(){ 
    auto c=someV(); 
    c *= 2.; 
    std::cout<<c; 
    return 0; 
} 

gibt das gewünschte Ergebnis zurück. Beachten Sie außerdem, dass die explizite Typdeklaration das Problem löst.

int main(){ 
    Eigen::VectorXd c=2.*someV(); 
    std::cout<<c; 
    return 0; 
} 

Warum ist die Verwendung von Auto im ersten Fall falsch?

+0

Ich vermute, dass dies etwas mit der Interaktion von Güssen und "Auto" zu tun hat. Könnten Sie versuchen, nicht "auto" zu verwenden, sondern explizit mit den Rückgabetypen und sehen, ob das Verhalten anders ist? – TriskalJM

+0

Welche Art von Werten erhalten Sie und welche Art erwarten Sie? – comingstorm

+0

Bitte können Sie eine SSCCE (http://sscce.org/) hinzufügen, so dass wir nicht erraten müssen, was die Eingaben sind, wie das Ergebnis anders ist als erwartet, usw. – NPE

Antwort

1

Eigen verwendet Expressionsvorlagen, um die Optimierung von Ausdrücken zu ermöglichen. Dies bedeutet, dass der Rückgabetyp keine Instanz von Eigen::VectorXd ist und stattdessen eine Vorlage ist, die die Operation darstellt, die alles auswertet, wenn sie einem Vektor zugewiesen wird. In Ihrem Fall wieder die Art von Typ ist

Eigen::MatrixBase<Eigen::Matrix<double, -1, 1>>::ScalarMultipleReturnType 

, die ein typedef von

Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, -1, 1>> 

Normalerweise ist dies in Ordnung sein würde, ist das Ergebnis zurück in einen Vektor umgewandelt werden, wenn sie zugeordnet ist. In Ihrem Fall wird es jedoch nicht zurückkonvertiert, da die auto als temporärer Ergebnistyp abgezogen wird. Dies war wahrscheinlich nicht von den Autoren der Bibliothek beabsichtigt und ist die Ursache für die Probleme, die Sie mit dem Drucken hatten.

Mit Ihrem zweiten Fall wird die als vom Typ Eigen::VectorXd abgeleitet. Dies bereitet keine Probleme beim Drucken mit std::cout.

+1

Eigentlich ist dies ein sehr verbreiteter Fehler und die [Autoren warnen] (http://eigen.tuxfamily.org/dox/TopicPitfalls.html) über die Verwendung von 'auto', wenn Sie nicht wissen, was Sie tun. –

+2

Und genauer gesagt ist das wahre Problem hier, dass das Objekt 'c' vom Typ' CwiseUnaryOp' einen Verweis auf den Vektor speichert, der von 'someV' zurückgegeben wird. Dieses Temporär wird direkt danach gelöscht, und diese Referenz wird somit ungültig ... Andererseits ist das Folgende in Ordnung: 'cout << 2. * someV();' – ggael