为什么以下代码会产生编译错误?
#include <iostream>
#include "gtest/gtest.h"
#include <utility>
namespace A {
//overloading operator << for std::pair
template<typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& p) {
return os << "pair:{" << p.first << ", " << p.second << "}";
}
struct C {
int x;
};
std::ostream& operator<<(std::ostream& os, const C& c) {
return os << c.x;
}
TEST(TestA, testA) {
std::pair<C, C> pair1;
std::pair<int, int> pair2;
EXPECT_EQ(0, 0) << pair1; //compiles
EXPECT_EQ(0, 0) << pair2; //doesn't compile
}
}
我使用Visual Studio 2015.错误文本是:
错误C2679二进制'&lt;&lt;':找不到右侧的操作符 'const std :: pair'类型的操作数(或者没有可接受的 转换)... \ gtest \ gtest-message.h 131
如何将用户定义的类型更改为内置类型会有所不同?
更新。感谢@Kerrek SB,解释了错误。但是,现在还有另一个问题:我应该如何重载operator&lt;&lt; std::pair
能否像我的代码一样使用它?
答案 0 :(得分:2)
我接受了你的回答并把它变成了一个最小的例子,消除了对谷歌代码的依赖:
#include <iostream>
namespace A {
template<typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& p) {
return os << "pair:{" << p.first << ", " << p.second << "}";
}
struct C {
int x;
};
std::ostream& operator<<(std::ostream& os, const C& c) {
return os << c.x;
}
void test() {
std::pair<C, C> pair1;
std::pair<int, int> pair2;
std::cout << pair1 << std::endl; // compiles
std::cout << pair2 << std::endl; // also compiles
}
}
int main(int argc, char *argv[]) {
A::test();
}
这实际上对我来说很好,输出
pair:{0, 0}
pair:{0, 0}
所以,我无法重现你的问题。但是,@ KerrekSB已经确定了解决问题的一个很好的理由。我怀疑差异可能在于你的代码在TEST中调用operator<<
,这是由Google Test包定义的某种类型的宏,而我的更小的例子用命名空间A
中的函数替换它,或许更改名称查找?
答案 1 :(得分:2)
当写一个像EXPECT_EQ(e1,e2) << some_pair
这样的东西时,模板函数
template<typename T>
::testing::Message::operator<<
正在实例化。只有在此函数内部才会调用用户定义的operator<<
。由于函数位于另一个命名空间(不在A
中),因此无法找到用户定义的operator<<
。
解决方案很简单。 Gtest提供接受STL容器的函数::testing::PrintToString
。所以代码应该是这样的(我改变它是有意义的):
EXPECT_TRUE(some_predicate(pair2)) << ::testing::PrintToString(pair2);
答案 2 :(得分:0)
您需要在 operator <<
命名空间中为 std::pair
定义 std
以便 gtest
找到它。
如下代码编译正常:
#include <iostream>
#include "gtest/gtest.h"
#include <utility>
namespace std
{
//overloading operator << for std::pair
template<typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
return os << "pair:{" << p.first << ", " << p.second << "}";
}
}
namespace A {
struct C {
int x;
};
std::ostream& operator<<(std::ostream& os, const C& c) {
return os << c.x;
}
TEST(TestA, testA) {
std::pair<C, C> pair1;
std::pair<int, int> pair2;
EXPECT_EQ(0, 0) << pair1; //compiles
EXPECT_EQ(0, 0) << pair2; //compiles!
}
}