UPDATE: Ich habe diesen Code der Frage vereinfacht, und entfernte den ursprünglichen, komplexeren Code.C++ - Operator << kompilieren Fehler mit gtest AssertionFailure
Bitte helfen Sie mir zu verstehen, was den Fehler verursacht, den ich unten beschreibe.
Ich habe einen einfachen 4xfloat Vektor Typ Vector4f
definiert. Vorläufig habe ich nur den Indexoperator definiert, aber irgendwann werde ich Operatoren für Addition, Subtraktion usw. definieren. Ich habe auch einen Stream-Operator für die Serialisierung des Vektors in einen Stream definiert. Nur öffentliche Methoden werden von diesem Operator verwendet, daher ist es kein friend
von Vector4f
.
vector.h:
#ifndef VECTOR_HPP
#define VECTOR_HPP
namespace vector {
class Vector4f {
public:
Vector4f(float x0, float x1, float x2, float x3) :
storage_({x0, x1, x2, x3}) {}
float & operator[](size_t i) { return storage_[i]; }
const float & operator[](size_t i) const { return storage_[i]; }
protected:
typedef std::vector<float> StorageType;
StorageType storage_;
};
template <typename StreamType>
StreamType & operator<<(StreamType & s, const Vector4f & v) {
return s << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
}
} // namespace vector
#endif // VECTOR_HPP
Ich Kompilieren mit C++ 11 (Klappern). Der Strom Serialisierung Vorlage scheint für Ostream zu arbeiten:
std::cout << vector::Vector4f(1,2,3,4) << std::endl; // compiles
Wo ich Probleme mit GoogleTest der AssertionFailure
Klasse ist, die mit einem Strom Operator verwendet werden kann, Informationen hinzuzufügen. Ich versuche, eine Hilfsfunktion zu verwenden, um zu überprüfen, dass ein Vektor die Werte enthält, die ich erwarte (ohne auf einen Gleichheitsoperator zu vertrauen, der noch nicht vorhanden ist). Der Einfachheit halber verwende ich die Behauptung direkt hier:
test_vector.cc:
#include <gtest/gtest.h>
#include "vector.h"
class TestVector : public ::testing::Test {};
TEST_F(TestVector, ctor_by_float_parameters) {
vector::Vector4f v(0.0f, 0.1f, 0.2f, 0.3f);
EXPECT_TRUE(::testing::AssertionFailure() << v);
}
Der Compiler mit diesem Fehler fehlschlägt:
In file included from test_vector2.cc:2:
./vector2.h:21:10: error: non-const lvalue reference to type 'std::__1::basic_stringstream<char,
std::__1::char_traits<char>, std::__1::allocator<char> >' cannot bind to a value of unrelated type
'basic_ostream<char, std::__1::char_traits<char> >'
return s << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
googletest/include/gtest/gtest-message.h:131:10: note: in instantiation of function template specialization
'vector::operator<<<std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> > >'
requested here
*ss_ << val;
^
googletest/include/gtest/gtest.h:306:29: note: in instantiation of function template specialization
'testing::Message::operator<<<vector::Vector4f>' requested here
AppendMessage(Message() << value);
^
test_vector2.cc:10:45: note: in instantiation of function template specialization
'testing::AssertionResult::operator<<<vector::Vector4f>' requested here
EXPECT_TRUE(::testing::AssertionFailure() << v);
Von dem, was ich verstehe, ist es mit Schwierigkeiten Anwenden des Ergebnisses der Vorlage operator<<
für meine Vector-Klasse auf die operator<<
für die Klasse testing :: AssertionFailure. Ich verstehe nicht, warum dies ein Problem verursacht, da es den Operator von AssertionFailure aufrufen sollte, nachdem es meinen Vektor in einen Stringstream serialisiert hat. Hier passiert etwas, was ich noch nicht verstehe, und ich verstehe die Fehlermeldung selbst nicht.
Jede Hilfe, bitte, bitte.
Das ist für mich zu viel Information. Bitte veröffentlichen Sie ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve). –
@RSahu ok, danke für deinen Rat. Ich habe meine Frage mit einer einfacheren Version aktualisiert, die denselben Compilerfehler aufweist. – meowsqueak
Ich verstehe nicht, warum Ihre 'operator <<' Funktion eine Vorlage sein muss und nicht einfach die Klasse 'std :: ostream' verwenden kann.Das würde wahrscheinlich das Problem die ganze Zeit beseitigen. –