C++ 编译器找不到重载
我最近正在为我的一些代码处理一些简单类型,并为它们重载插入运算符,以便它们可以轻松打印。我遇到了一个案例,我真的吐了上千行。简化版本如下:C++ 编译器找不到重载,c++,linux,namespaces,c++14,C++,Linux,Namespaces,C++14,我最近正在为我的一些代码处理一些简单类型,并为它们重载插入运算符,以便它们可以轻松打印。我遇到了一个案例,我真的吐了上千行。简化版本如下: #include <iostream> #include <sstream> #include <utility> #include <string> namespace ns{ template<typename KEY, typename VALUE> using KeyValue = std
#include <iostream>
#include <sstream>
#include <utility>
#include <string>
namespace ns{
template<typename KEY, typename VALUE>
using KeyValue = std::pair<KEY, VALUE>;
template<typename K, typename V>
inline std::ostream& operator<< (std::ostream& os, const KeyValue<K,V>& arg){
os << "Key: " << arg.first << " Value: " << arg.second;
return os;
}
}
struct Foo_t{
double a = 0;
};
inline std::ostream& operator<< (std::ostream& os, const Foo_t& f){
os << "a: " << f.a;
return os;
}
int main()
{
Foo_t foo{6.283185};
ns::KeyValue<std::string, Foo_t> foo_kv{"Foo_t", foo};
std::ostringstream oss;
oss << foo_kv;
std::cout << oss.str();
}
#包括
#包括
#包括
#包括
名称空间ns{
模板
使用KeyValue=std::pair;
模板
内联std::ostream&operatorKeyValue
是std::pair
的别名。定义别名模板的命名空间不被视为ADL的关联命名空间。将只考虑类std::pair
本身的类和封闭命名空间范围
因此,未找到ns
内的操作员过载
如果将Foo\u t
移动到ns
内部,则会发现此问题,因为ADL会考虑函数参数类型中类型模板参数的类作用域和封闭命名空间作用域
如果Foo\u t
在ns
内,则将ns
添加到将要搜索的关联作用域列表中,因为它是Foo\u kv
类类型的类型模板参数。如果在全局命名空间作用域中声明了Foo\u t
,则只添加全局命名空间作用域(仍由非限定查找搜索)
至于如何修复:如果您希望无论使用何种模板参数都能找到运算符重载,则可以将KeyValue
设置为一种不同的类型:
template<typename KEY, typename VALUE>
struct KeyValue : std::pair<KEY, VALUE> {
using std::pair<KEY, VALUE>::pair;
};
模板
结构键值:std::pair{
使用std::pair::pair;
};
或者您可以将运算符重载移动到全局命名空间中。看起来像是命名空间问题。我可以通过使用ns::operator添加来解决此问题。请看以下内容: