拥有std::pair
个引用是否有效?特别是,赋值运算符是否存在问题?根据{{3}},似乎没有对operator =进行特殊处理,因此无法生成默认的assignement运算符。
我想要一个pair<T&, U&>
,并能够为其分配另一对(值或引用)并修改指向的对象。
答案 0 :(得分:31)
不,你不能在C ++ 03中可靠地执行此操作,因为pair
的构造函数接受T
的引用,并在T&
中创建reference to a reference is not legal C ++ 03。
请注意,我说“可靠”。一些常用的编译器仍然在使用(对于GCC,我测试了GCC4.1,@Charles报告了GCC4.4.4)不允许形成对引用的引用,但最近做允许它它们实现参考折叠(如果T
是引用类型,则T
为boost::tuple<>
)。如果您的代码使用了这些东西,那么在您尝试并查看之前,您不能依赖它来处理其他编译器。
听起来你想使用int a, b;
// on the fly
boost::tie(a, b) = std::make_pair(1, 2);
// as variable
boost::tuple<int&, int&> t = boost::tie(a, b);
t.get<0>() = 1;
t.get<1>() = 2;
{{1}}
答案 1 :(得分:24)
在C ++ 11中,您可以使用std::pair<
std::reference_wrapper
<T>, std::reference_wrapper<U>>
,该类型的对象将完全按照您的意愿运行。
答案 2 :(得分:7)
我认为拥有std::pair
住房参考资料是合法的。毕竟,std::map
使用std::pair
类型const
,无法将其分配给任何一种类型。
我想要
pair<T&, U&>
并能够为其分配另一对
分配无效,因为您无法重置参考。但是,您可以复制初始化此类对象。
答案 3 :(得分:2)
你是对的。您可以创建一对引用,但不能再使用operator =
。
答案 4 :(得分:2)
template <class T1, class T2> struct refpair{
T1& first;
T2& second;
refpair(T1& x, T2& y) : first(x), second(y) {}
template <class U, class V>
refpair<T1,T2>& operator=(const std::pair<U,V> &p){
first=p.first;
second=p.second;
return *this;
}
};
它允许你做一些可怕的事情,如:
int main (){
int k,v;
refpair<int,int> p(k,v);
std::map<int,int>m;
m[20]=100;
m[40]=1000;
m[60]=3;
BOOST_FOREACH(p,m){
std::cout << "k, v = " << k << ", " << v << std::endl;
}
return 0;
}
(记住相关的内容)。
当然,我所分配的对k
和v
的引用隐藏在p
内。
如果你做这样的事情,它几乎会变得漂亮:
template <class T1,class T2>
refpair<T1,T2> make_refpair (T1& x, T2& y){
return ( refpair<T1,T2>(x,y) );
}
允许你像这样循环:
BOOST_FOREACH(make_refpair(k,v),m){
std::cout << "k, v = " << k << ", " << v << std::endl;
}
(欢迎所有评论,因为我绝不是c ++专家。)
答案 5 :(得分:1)
我不知道C ++ 03中std::pair
的“错误”是什么,但如果我天真地重新实现它,我就没有任何问题,(使用相同的编译器{{1}和gcc
)。
clang
因此,解决方法可能是(1)重新实现double a = 1.;
double b = 2.;
my::pair<double, double> p1(5., 6.);
my::pair<double&, double&> p2(a, b);
p2 = p1; // a == 5.
(在不同的命名空间中),或(2)专门用于pair
,或者(3)简单地使用C ++ 11(其中{ {1}}对于refs开箱即用)
(1)这是天真的实现
std::pair<T&, T&>
(2)这里是std::pair
的一个特化(有些人可能会抱怨我在使用namespace my{
template<class T1, class T2>
struct pair{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(T1 const& t1, T2 const& t2) : first(t1), second(t2){}
template<class U1, class U2> pair(pair<U1, U2> const& p) : first(p.first), second(p.second){}
template<class U1, class U2>
pair& operator=(const pair<U1, U2>& p){
first = p.first;
second = p.second;
return *this;
}
};
template<class T1, class T2>
pair<T1, T2> make_pair(T1 t1, T2 t2){
return pair<T1, T2>(t1, t2);
}
}
命名空间进行重载/专攻,但我认为如果是扩展类的功能)
std::pair
也许我错过了一些明显的东西,如果有明显的缺陷,我可以编辑答案。
答案 6 :(得分:0)
发布 c++14,你可以这样做:
int a, b;
auto const p(std::make_pair(std::ref(a), std::ref(b)));
也可以使用 std::cref()
。
答案 7 :(得分:-1)
我最后通过构建一个非常简单的结构解决了类似的问题。我甚至不担心赋值运算符,因为默认运算符应该可以正常工作。
template<class U, class V>
struct pair
{
pair(U & first, V & second): first(first), second(second) {}
U & first;
V & second;
}