std ::引用对

时间:2010-09-22 13:35:16

标签: c++ std

拥有std::pair个引用是否有效?特别是,赋值运算符是否存在问题?根据{{​​3}},似乎没有对operator =进行特殊处理,因此无法生成默认的assignement运算符。

我想要一个pair<T&, U&>,并能够为其分配另一对(值或引用)并修改指向的对象。

8 个答案:

答案 0 :(得分:31)

不,你不能在C ++ 03中可靠地执行此操作,因为pair的构造函数接受T的引用,并在T&中创建reference to a reference is not legal C ++ 03。

请注意,我说“可靠”。一些常用的编译器仍然在使用(对于GCC,我测试了GCC4.1,@Charles报告了GCC4.4.4)不允许形成对引用的引用,但最近允许它它们实现参考折叠(如果T是引用类型,则Tboost::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;
}

(记住相关的内容)。

当然,我所分配的对kv的引用隐藏在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;
}