论坛首页 编程语言技术论坛

C++ std名字空间ostream_iterator与的诡异问题

浏览 9010 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-05-09  
C++
为了方便显示map而自定义的两个函数,出现了一个诡异的问题,感谢jinq0123@163.com告之解决方法,但是我对问题的原因还是不太清楚.

这里的Blog好像有问题,我把<该为了《........................

cpp 代码
 
  1. #include 《map》  
  2. #include 《string》  
  3. #include 《iterator》  
  4. #include 《iostream》  
  5.   
  6. using namespace std;  
  7. namespace std     
  8. {     
  9.      //如果不将该函数放入名字空间std则使用ostream_iterator不能通过编译  
  10.      //但是可以直接用cout输出pair  
  11.   
  12.     templateclass _Elem,class _Traits,class K,class V》  
  13.     basic_ostream《_Elem,_Traits》& operator《《(  
  14.         basic_ostream《_Elem,_Traits》& s  
  15.         ,  
  16.         const pair《K,V》& p  
  17.         )  
  18.     {  
  19.         return s《《p.first《《" : "《《p.second;  
  20.     }  
  21.   
  22. }  
  23.   
  24. templateclass _Elem,class _Traits,class K,class V》  
  25. basic_ostream《_Elem,_Traits》&  operator《《(  
  26.     basic_ostream《_Elem,_Traits》& s  
  27.     ,   
  28.     const map《K,V》& m  
  29. )  
  30. {  
  31.     copy(m.begin(), m.end(), ostream_iterator《pair《K,V》 》(s, "\n"));  
  32.     return s;  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.     using namespace std;  
  38.     map《string,string》 a;  
  39.     a["key1"]="value1";  
  40.     a["key2"]="value2";  
  41.     cout《《a;  
  42.     system("pause");  
  43.     return 0;  
  44. }  
   发表时间:2007-05-10  
名称查找的问题吧 …… 可能是类模板中对引用名字做两段式查找的时候按照类模板定义点来了,不太确定这个行为是否符合标准。

转去 www.cpper.com/c/ 问这个问题吧。
0 请登录后投票
   发表时间:2007-05-15  
因为otream_iterator的定义在std里,所以它首先会在std里查找operator》,只要找到一个名字一样的(尽管可能参数不一样),就不会继续到global namespace里查找了
这个确实是标准规定的
0 请登录后投票
   发表时间:2007-05-15  

> using namespace std;
> namespace std
> {
>        //If don't put this function into namespace std , there will be
> a
> compile error .

>        template<class _Elem,class _Traits,class K,class V>
>        basic_ostream<_Elem,_Traits>& operator<<(
>                basic_ostream<_Elem,_Traits>& s
>                ,
>                const pair<K,V>& p
>                )
>        {
>                return s<<p.first<<" : "<<p.second;
>        }

> }

> template<class _Elem,class _Traits,class K,class V>
> basic_ostream<_Elem,_Traits>&  operator<<(
>        basic_ostream<_Elem,_Traits>& s
>        ,
>        const map<K,V>& m
> )
> {
>        copy(m.begin(), m.end(), ostream_iterator<pair<K,V> >(s,
> "\n"));
>        return s;

> }

> int main()
> {
>        using namespace std;
>        map<string,string> a;
>        a["key1"]="value1";
>        a["key2"]="value2";
>        cout<<a;
>        system("pause");
>        return 0;

> }

We had a similar discussion some time ago.
Please read http://tinyurl.com/yvca6w for the
details (If this link does not lead to the correct
entry, please read contribution 14).

The short version is: Don't do that! You are not
allowed to add such an overload to namespace
std which brings you in the realm of undefined
behaviour. The above quoted thread shows in
contribution 14 that there are at least two clean
solutions:

1) Change your operator template overload by a corresponding function template (e.g. "print") in your user namespace. Then replace your std::copy invocation by a std::for_each call (which uses a special print functor and *not* operator<< on std::pair) or use an explicit loop.

2) Use a better customizable iterator like boost::transform_iterator which uses the print-functor mentioned in (1).

Greetings from Bremen,

Daniel Krügler
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics