【问题标题】:template ostream operator overload for stl mapstl 映射的模板 ostream 运算符重载
【发布时间】:2014-07-12 12:33:18
【问题描述】:

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

此代码在编译时出现以下错误:

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>] 

请建议如何消除这种歧义

【问题讨论】:

    标签: templates map namespaces overloading ostream


    【解决方案1】:

    我只会解释问题,但如果没有您方面的进一步信息,很难提出解决方案。

    第一个问题是header中声明的operator&lt;&lt;没有实现。您在head.cpp 中添加的实现具有不同的签名,由于它没有在标头中声明,main.cpp 将永远找不到它。

    第二个问题是即使声明的operator&lt;&lt; 也找不到。您可能认为您可以依靠 ADL 来找到它,但这仅在 bla 是同一命名空间中的类型时才有效。但是ns::StrIntMaptypedef,而不是类型本身,因此它等价于std::map&lt;std::string,int&gt;。 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&lt;&lt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      相关资源
      最近更新 更多