C ++运算符<<使用gtest编译错误AssertionFailure

时间:2016-06-23 05:32:48

标签: c++ templates c++11 googletest crtp

更新:我简化了这个问题的代码,删除了原始的,更复杂的代码。

请帮助我了解导致我在下面描述的错误的原因。

我定义了一个简单的4xfloat向量类型Vector4f。现在我只定义了索引运算符,但最终我将为加法,减法等定义运算符。我还定义了一个流运算符,用于将向量序列化为流。此运算符仅使用公共方法,因此它不是friend的{​​{1}}。

vector.h:

Vector4f

我正在使用C ++ 11(clang)进行编译。流序列化模板似乎适用于ostream:

#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

我遇到问题的地方是GoogleTest的std::cout << vector::Vector4f(1,2,3,4) << std::endl; // compiles 类,它可以与流操作符一起使用来添加信息。我希望最终使用辅助函数来检查向量是否包含我期望的值(不依赖于尚不存在的相等运算符)。为简单起见,我在这里直接使用断言:

test_vector.cc:

AssertionFailure

编译器因此错误而失败:

#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);
}

根据我的理解,将我的Vector类的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); 模板的结果应用于test :: AssertionFailure类的operator<<时遇到问题。我不明白为什么这会引起问题,因为它应该在将我的矢量序列化为字符串流后调用AssertionFailure的运算符。这里有一些我还不了解的东西,我当然不理解错误信息本身。

请帮助表示任何帮助。

1 个答案:

答案 0 :(得分:2)

template<class... Us>
struct interleave {
     template<class... Vs>
     using with = concat_t<pack<Us, Vs>...>;
};

应该是

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,而不是您调用它的流的类型。您无法将其转换为std::basic_ostream<...>&,除非StreamType&恰好是StreamTypebasic_ostream就是这种情况。

或者,将std::cout声明为

operator<<