重载运算符>>对于std :: pair< int,int> [英] Overload operator>> for std::pair<int, int>

查看:194
本文介绍了重载运算符>>对于std :: pair< int,int>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 std :: pair< int,int> 上使用 boost :: lexical_cast

  #include< iostream> 
#include< utility>
#include< boost / lexical_cast.hpp>

命名空间my
{
//当my_pair是用户定义的类型时,此程序将编译
//并运行,不会出现任何问题。
//将my_pair声明为std :: pair< int,int> ;,
的别名时//无法编译

/ *
struct my_pair
{首先是
int;
int秒;
};
* /

使用my_pair = std :: pair< int,int> ;;

std :: istream&操作符>>(std :: istream& stream,my_pair& pair)
{
stream>>一对第一;
流>> std :: skipws;
流>> pair.second;
返回流;
}
}

int main()
{
my :: my_pair p = boost :: lexical_cast< my :: my_pair>( 10 10);
std :: cout<< p。第一<< << p.second<< std :: endl;
返回0;
}

如果我理解正确,为了使ADL正常运行,运营商>>



这样做会导致未定义的行为,因为我要向命名空间std添加函数。



p>

我想避免继承,例如 struct my_pair:std :: pair< int,int> p>

该问题的解决方案是什么?



我在OS X上使用clang ++-3.6。

解决方案

您可以在流上重载(以某种方式对其进行标记),而不是对要传输的值进行ADL挂钩:

  int main(){
std :: map< int,std :: string>备用{{42,我要尝试},{1729,科学}};

stream :: tag_ostream out = std :: cout;

for(自动&进入:备用)
out<<条目<< \n;
}

这样,您可以将ADL钩在您控制的名称空间上。您可以使标记更通用(请考虑 auto out = stream :: tag(std :: cout))。



现在,它的一个简单实现看起来像是

 命名空间流{

模板<类型名T>
结构标记:std :: reference_wrapper< T> {
使用std :: reference_wrapper< T> :: reference_wrapper;
};

使用tag_ostream = tag< std :: ostream> ;;

模板< typename T1,typename T2>
静态内嵌tag_ostream运算符<(tag_ostream os,std :: pair< T1,T2> const& p){
os.get()<< std :: pair {<< p。第一<< ,<< p.second<< };
return os;
}

模板< typename其他>
静态内嵌tag_ostream运算符<(tag_ostream os,其他const&o){
os.get()<< o;
return os;
}
}

查看它 在Coliru上直播 ,其中显示:

  std :: pair {42,我要尝试} 
std :: pair {1729,science}


I am trying to use boost::lexical_cast on a std::pair<int, int>.

#include <iostream>
#include <utility>
#include <boost/lexical_cast.hpp>

namespace my
{
  // When my_pair is a user defined type, this program compiles
  // and runs without any problems.
  // When declaring my_pair as an alias of std::pair<int, int>,
  // it fails to compile

  /*
  struct my_pair
  {
      int first;
      int second;
  };
  */

  using my_pair = std::pair<int, int>;

  std::istream& operator>>(std::istream& stream, my_pair& pair)
  {
    stream >> pair.first;
    stream >> std::skipws;
    stream >> pair.second;
    return stream;
  }
}

int main()
{
  my::my_pair p = boost::lexical_cast<my::my_pair>("10 10");
  std::cout << p.first << " " << p.second << std::endl;
  return 0;
}

If I understand right, in order to make ADL work, the operator>> has to be in the same namespace as my_pair, so std.

Doing so, would result in undefined behavior, because I would be adding functions to the namespace std.

I would like to avoid inheritance, as in struct my_pair : std::pair<int, int>.

What could be the solution to this problem?

I am using clang++-3.6 on OS X.

解决方案

Instead of ADL-hooking on the value to stream, you could overload on the stream (tagging it in some way):

int main() {
    std::map<int, std::string> standback { { 42, "I'm gonna try" }, { 1729, "science" } };

    streaming::tag_ostream out = std::cout;

    for (auto& entry : standback)
        out << entry << "\n";
}

This way, you can ADL-hook on a namespace that is under your control. You can make the tagging more generic (think auto out = streaming::tag(std::cout)).

Now, a simple implementation of that could look like

namespace streaming {

    template <typename T>
    struct tag : std::reference_wrapper<T> {
        using std::reference_wrapper<T>::reference_wrapper;
    };

    using tag_ostream = tag<std::ostream>;

    template <typename T1, typename T2>
    static inline tag_ostream operator<<(tag_ostream os, std::pair<T1, T2> const& p) {
        os.get() << "std::pair{" << p.first << ", " << p.second  << "}";
        return os;
    }

    template <typename Other>
    static inline tag_ostream operator<<(tag_ostream os, Other const& o) {
        os.get() << o;
        return os;
    }
}

See it Live On Coliru, which prints:

std::pair{42, I'm gonna try}
std::pair{1729, science}

这篇关于重载运算符&gt;&gt;对于std :: pair&lt; int,int&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆