在以下场景中,在函数()内部ss << bb
,我收到一个错误:
binary'&lt;&lt;':找不到带有'CommonType'类型(或没有可接受的转换)错误的右手操作数的运算符。
我的ADL理解是它会查看当前的命名空间(即AppNamespace::InnerNamespace
)并且由于找不到operator <<
,它将查看参数的命名空间并作为{{1在全局命名空间中,我希望找到CommonTypes.h中定义的CommonType
。
显然我的理解是错误的。任何人都可以弄清楚这应该如何工作?
Main.cpp的
operator <<
CommonTypes.h:
namespace AppNamespace
{
typedef std::vector<std::string> OtherType;
std::ostream& operator << (std::ostream& os, const OtherType& ot)
{
for (auto& el : ot)
{
os << el;
}
return os;
}
namespace InnerNamespace
{
void function()
{
CommonType bb;
std::stringstream ss;
ss << bb;
}
}
}
int main()
{
AppNamespace::InnerNamespace::function();
return 0;
}
答案 0 :(得分:1)
这里的问题是ADL查找将在std
命名空间和命名空间中执行,其中声明CommonType
是不相关的,因此为了使这项工作,您需要放置运算符&lt;&lt;在适当的命名空间中:
namespace std
{
ostream& operator << (ostream& os, const CommonType& bb)
{
for (auto& el : bb)
{
os << el;
}
return os;
}
}
答案 1 :(得分:1)
我的ADL理解是它会查看当前的命名空间(即
AppNamespace::InnerNamespace
),因为没有&lt;&lt;找到运算符,它将查看参数的namespace
,并且CommonType
在全局命名空间中,我希望&lt;&lt;在CommonTypes.h中定义的运算符。
误解是CommonType
是一种新类型。它不是一种新型的。这只是一个别名。
您可以使用各种方法解决函数查找问题。
在全局命名空间中定义operator<<
个函数。
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <cstdint>
// Put everything from CommonTypes.h here to simplify things.
typedef std::vector<uint8_t> CommonType;
std::ostream& operator<<(std::ostream& os, CommonType const& bb)
{
for (auto& el : bb)
{
os << el;
}
return os;
}
namespace AppNamespace
{
typedef std::vector<std::string> OtherType;
}
std::ostream& operator << (std::ostream& os, const AppNamespace::OtherType& ot)
{
for (auto& el : ot)
{
os << el;
}
return os;
}
namespace AppNamespace
{
namespace InnerNamespace
{
void function()
{
CommonType bb;
std::stringstream ss;
ss << bb;
}
}
}
int main()
{
AppNamespace::InnerNamespace::function();
return 0;
}
在operator<<
命名空间中定义AppNamespace
个函数。
#include <iostream>
#include <vector>
#include <cstdint>
// Put everything from CommonTypes.h here to simplify things.
typedef std::vector<uint8_t> CommonType;
namespace AppNamespace
{
std::ostream& operator<<(std::ostream& os, CommonType const& bb)
{
for (auto& el : bb)
{
os << el;
}
return os;
}
typedef std::vector<std::string> OtherType;
std::ostream& operator << (std::ostream& os, const OtherType& ot)
{
for (auto& el : ot)
{
os << el;
}
return os;
}
namespace InnerNamespace
{
void function()
{
CommonType bb;
std::stringstream ss;
ss << bb;
}
}
}
int main()
{
AppNamespace::InnerNamespace::function();
return 0;
}
在另一个命名空间中定义std::ostream& operator<<(std::ostream& os, CommonType const& bb)
并明确将该函数放入AppNamespace
的范围内。
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <cstdint>
// Put everything from CommonTypes.h here to simplify things.
typedef std::vector<uint8_t> CommonType;
namespace CommonNamespace
{
std::ostream& operator<<(std::ostream& os, CommonType const& bb)
{
for (auto& el : bb)
{
os << el;
}
return os;
}
}
namespace AppNamespace
{
// Bring the operator<< functions in CommonNamespace into the scope of
// this namespace.
using CommonNamespace::operator<<;
typedef std::vector<std::string> OtherType;
std::ostream& operator << (std::ostream& os, const OtherType& ot)
{
for (auto& el : ot)
{
os << el;
}
return os;
}
namespace InnerNamespace
{
void function()
{
CommonType bb;
std::stringstream ss;
ss << bb;
}
}
}
int main()
{
AppNamespace::InnerNamespace::function();
return 0;
}
答案 2 :(得分:0)
如果您不想按照VTT的建议在std
命名空间中移动运算符,则可以指定它位于全局命名空间中:
(::operator <<)(ss, bb);