UPDATE: Я упростил этот вопрос и удалил оригинальный, более сложный код.Оператор на C++ << скомпилировать ошибку с gtest AssertionFailure
Пожалуйста, помогите мне понять, что вызывает ошибку, описанную ниже.
Я определил простой вектор 4xfloat типа Vector4f
. На данный момент я только определил оператор индекса, однако в конечном итоге я буду определять операторы для сложения, вычитания и т. Д. Я также определил оператор потока для сериализации вектора к потоку. Этот оператор использует только общедоступные методы, поэтому он не является friend
от 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
Я компиляции с C++ 11 (лязг). Шаблон потока сериализации, кажется, работает для ostream:
std::cout << vector::Vector4f(1,2,3,4) << std::endl; // compiles
Где я сталкиваюсь проблем с AssertionFailure
класса GoogleTest в, который может быть использован с оператором потока для добавления информации. Я ищу в конце концов использовать вспомогательную функцию, чтобы проверить, что вектор содержит ожидаемые значения (не полагаясь на оператор равенства, который еще не существует). Для простоты я использую утверждение прямо здесь:
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);
}
Компилятор терпит неудачу с этой ошибкой:
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);
Из того, что я понимаю, что есть проблема, применение результата шаблона operator<<
для моего класса Vector для operator<<
для тестирования: класс AssertionFailure. Я не понимаю, почему это вызывает проблему, поскольку она должна вызывать оператор AssertionFailure после того, как он сериализовал мой вектор в поток строк. Здесь что-то происходит, я еще не понимаю, и я, конечно, не понимаю самого сообщения об ошибке.
Любая помощь приветствуется, пожалуйста.
Это слишком много информации для меня. Пожалуйста, напишите [Минимальный, Полный и Подтверждаемый пример] (http://stackoverflow.com/help/mcve). –
@RSahu хорошо, спасибо за ваш совет. Я обновил свой вопрос с более простой версией, которая демонстрирует ту же ошибку компилятора. – meowsqueak
Я не понимаю, почему ваша функция 'operator <<' должна быть шаблоном и не может просто использовать класс' std :: ostream'.Вероятно, это устранит проблему. –