head.hpp
#include <algorithm>
#include <map>
#include <string>
namespace ns
{
typedef std::map<std::string, int> StrIntMap;
template<typename T1, typename T2>
std::ostream &operator<<(std::ostream &stream, const std::map<T1, T2>& map);
};
head.cpp
#include "head.hpp"
template<typename T1>
std::ostream & ns::operator<<(std::ostream &stream, const ns::T1& map)
{
for (ns::T1::const_iterator it = map.begin();
it != map.end(); ++it)
{
stream << (*it).first << " --> " << (*it).second << std::endl;
}
return stream;
}
的main.cpp
#include <map>
#include <string>
#include <iostream>
#include "head.hpp"
int main(int, char **)
{
ns::StrIntMap bla;
bla["one"] = 1;
bla["two"] = 2;
std::cout << bla << std::endl;
return (0);
}
此代码在compliation时出现以下错误:
main.cpp no match for 'operator<<' in 'std::cout << bla'
note C:\Dev-Cpp\include\c++\3.4.2\bits\ostream.tcc:63 candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
note C:\Dev-Cpp\include\c++\3.4.2\bits\ostream.tcc:63 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT, _Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
note C:\Dev-Cpp\include\c++\3.4.2\bits\ostream.tcc:63 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base&(*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]
请建议如何消除这种歧义
答案 0 :(得分:0)
我只会解释这个问题,但如果没有您方的进一步信息,很难找到解决方案。
第一个问题是标头中声明的operator<<
未实现。您在head.cpp
中添加的实施具有不同的签名,因为它未在标题中声明,main.cpp
将永远找不到它。
第二个问题是即使声明的operator<<
也找不到。您可能认为您可以依赖ADL来查找它,但这仅在bla
是同一名称空间中的类型时才有效。但ns::StrIntMap
是typedef
,而不是类型本身,因此它等同于std::map<std::string,int>
。 ADL只会查找名称空间std
的候选项,而不是名称空间ns
。
我看到的一个选项是用实际类型替换typedef:
struct StrIntMap : std::map<std::string,int>
{
// C++11 allows you to inherit all ctors from the base class:
using std::map<std::string,int>::map;
};
并尝试为此实现operator<<
。