jeudi 23 juin 2016

C++ operator<< compile error with gtest AssertionFailure


UPDATE: I have simplified this question's code, and removed the original, more complex code. Please help me understand what is causing the error I describe below. I have defined a simple 4xfloat vector type Vector4f. For now I have only defined the index operator, however eventually I will define operators for addition, subtraction, etc. I have also defined a stream operator for serialisation of the vector to a stream. Only public methods are used by this operator, so it is not a friend of 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 I'm compiling with C++11 (clang). The stream serialisation template seems to work for ostream: std::cout << vector::Vector4f(1,2,3,4) << std::endl; // compiles Where I run into problems is with GoogleTest's AssertionFailure class, that can be used with a stream operator to add information. I'm looking to eventually use a helper function to check that a vector contains the values I expect (without relying on an equality operator that doesn't yet exist). For simplicity, I'm using the assertion directly here: 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); } The compiler fails with this error: 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); From what I understand, it is having trouble applying the result of the operator<< template for my Vector class to the operator<< for the testing::AssertionFailure class. I don't understand why this is causing a problem as it ought to be invoking the AssertionFailure's operator after it has serialised my vector into a stringstream. There's something going on here that I don't yet understand, and I certainly don't understand the error message itself. Any help appreciated, please.

Aucun commentaire:

Enregistrer un commentaire