C++ operator<< gtest AssertionFailure 编译错误
C++ operator<< compile error with gtest AssertionFailure
更新:我已经简化了这个问题的代码,并删除了原来的、更复杂的代码。
请帮助我了解导致我在下面描述的错误的原因。
我定义了一个简单的 4xfloat 向量类型 Vector4f
。现在我只定义了索引运算符,但最终我会定义加法、减法等运算符。我还定义了一个流运算符,用于将向量序列化为流。此运算符仅使用 public 方法,因此它不是 Vector4f
的 friend
。
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 (clang) 进行编译。流序列化模板似乎适用于 ostream:
std::cout << vector::Vector4f(1,2,3,4) << std::endl; // compiles
我 运行 遇到问题的地方是 GoogleTest 的 AssertionFailure
class,它可以与流运算符一起使用以添加信息。我希望最终使用辅助函数来检查向量是否包含我期望的值(不依赖于尚不存在的相等运算符)。为简单起见,我在这里直接使用断言:
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);
据我所知,将 Vector class 的 operator<<
模板的结果应用到 testing::AssertionFailure [=45] 的 operator<<
时遇到问题=].我不明白为什么这会导致问题,因为它应该在将我的向量序列化为字符串流后调用 AssertionFailure 的运算符。这里发生了一些我还不明白的事情,我当然也不明白错误消息本身。
请提供任何帮助。
return s << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
应该是
s << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
return s;
这是因为 operator<<(float)
是 std::basic_ostream
的 成员函数 。它 returns std::basic_ostream<...>&
,不是你调用它的流的类型。您无法将其转换为 StreamType&
,除非 StreamType
恰好是 basic_ostream
,std::cout
.
就是这种情况
或者,将您的 operator<<
声明为
template <typename VectorType, typename... StreamArgs>
std::basic_ostream<StreamArgs...> &
operator << (std::basic_ostream<StreamArgs...>& s,
const BaseVector<VectorType> & v)
更新:我已经简化了这个问题的代码,并删除了原来的、更复杂的代码。
请帮助我了解导致我在下面描述的错误的原因。
我定义了一个简单的 4xfloat 向量类型 Vector4f
。现在我只定义了索引运算符,但最终我会定义加法、减法等运算符。我还定义了一个流运算符,用于将向量序列化为流。此运算符仅使用 public 方法,因此它不是 Vector4f
的 friend
。
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 (clang) 进行编译。流序列化模板似乎适用于 ostream:
std::cout << vector::Vector4f(1,2,3,4) << std::endl; // compiles
我 运行 遇到问题的地方是 GoogleTest 的 AssertionFailure
class,它可以与流运算符一起使用以添加信息。我希望最终使用辅助函数来检查向量是否包含我期望的值(不依赖于尚不存在的相等运算符)。为简单起见,我在这里直接使用断言:
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);
据我所知,将 Vector class 的 operator<<
模板的结果应用到 testing::AssertionFailure [=45] 的 operator<<
时遇到问题=].我不明白为什么这会导致问题,因为它应该在将我的向量序列化为字符串流后调用 AssertionFailure 的运算符。这里发生了一些我还不明白的事情,我当然也不明白错误消息本身。
请提供任何帮助。
return s << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
应该是
s << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
return s;
这是因为 operator<<(float)
是 std::basic_ostream
的 成员函数 。它 returns std::basic_ostream<...>&
,不是你调用它的流的类型。您无法将其转换为 StreamType&
,除非 StreamType
恰好是 basic_ostream
,std::cout
.
或者,将您的 operator<<
声明为
template <typename VectorType, typename... StreamArgs>
std::basic_ostream<StreamArgs...> &
operator << (std::basic_ostream<StreamArgs...>& s,
const BaseVector<VectorType> & v)