重载运算符>>对于std :: pair< int,int> [英] Overload operator>> for 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}
这篇关于重载运算符>>对于std :: pair< int,int>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!