C++ std:: 对引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3769781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:39:38  来源:igfitidea点击:

std::pair of references

c++std

提问by Alexandre C.

Is it valid to have a std::pairof references ? In particular, are there issues with the assignment operator ? According to this link, there seems to be no special treatment with operator=, so default assignement operator will not be able to be generated.

std::pair参考文献是否有效?特别是,赋值运算符有问题吗?根据此链接,operator= 似乎没有特殊处理,因此将无法生成默认赋值运算符。

I'd like to have a pair<T&, U&>and be able to assign to it another pair (of values or references) and have the pointed-to objects modified.

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

采纳答案by Johannes Schaub - litb

No, you cannotdo this reliably in C++03, because the constructor of pairtakes references to T, and creating a reference to a reference is not legalin C++03.

不,您不能在 C++03 中可靠地执行此操作,因为 的构造函数pair接受对 的引用T,并且在 C++03 中创建对引用的引用是不合法的

Notice that I said "reliably". Some common compilers still in use (for GCC, I tested GCC4.1, @Charlesreported GCC4.4.4) do not allow forming a reference to a reference, but more recently doallow it as they implement reference collapsing (T&is Tif Tis a reference type). If your code uses such things, you cannot rely on it to work on other compilers until you try it and see.

请注意,我说的是“可靠”。一些常见的编译器仍在使用(GCC,我测试GCC4.1,@Charles报道GCC4.4.4)不允许形成于基准的基准,但最近允许它作为他们执行基准崩溃(T&T,如果T是一个参考类型)。如果你的代码使用了这些东西,你不能依赖它在其他编译器上工作,除非你尝试看看。

It sounds like you want to use boost::tuple<>

听起来你想用 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;

回答by Johannes Schaub - litb

In C++11 you can use std::pair<std::reference_wrapper<T>, std::reference_wrapper<U>>and the objects of that type will behave exactly as you want.

在 C++11 中,您可以使用该类型的对象,其行为将完全符合您的要求。std::pair<std::reference_wrapper<T>, std::reference_wrapper<U>>

回答by sbi

I think it would be legal to have a std::pairhousing references. std::mapuses std::pairwith a consttype, after all, which can't be assigned to either.

我认为拥有std::pair房屋推荐信是合法的。std::map用途std::pairconst类型,毕竟不能被分配到。

I'd like to have a pair<T&, U&>and be able to assign to it another pair

我想要一个pair<T&, U&>并且能够分配给它另一对

Assignment won't work, since you cannot reset references. You can, however, copy-initialize such objects.

分配不起作用,因为您无法重置引用。但是,您可以复制初始化此类对象。

回答by MrMasterplan

I was thinking along the same lines as you, I think. I wrote the following class to scratch this particular itch:

我和你的想法一样,我想。我编写了以下课程来解决这个特殊的问题:

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;
        }
};

It allows you to do horrible things like:

它允许你做一些可怕的事情,比如:

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;
}

(remember the relevant includes).

(记住相关的include)。

The nastiness is of course that the references to kand vthat I am assigning to are hidden inside p. It almost becomes pretty again if you do something like this:

令人讨厌的当然是对kv我分配的引用隐藏在p. 如果你做这样的事情,它几乎又变得漂亮了:

template <class T1,class T2>
refpair<T1,T2> make_refpair (T1& x, T2& y){
    return ( refpair<T1,T2>(x,y) );
}

Which allows you to loop like this:

这允许您像这样循环:

BOOST_FOREACH(make_refpair(k,v),m){
    std::cout << "k, v = " << k << ", " << v << std::endl;      
}

(All comments are welcome as I am in no way a c++ expert.)

(欢迎所有评论,因为我绝不是 C++ 专家。)

回答by ybungalobill

You are right. You can create a pair of references, but you can't use operator =anymore.

你是对的。您可以创建一对引用,但不能再使用operator =

回答by alfC

I don't know what is "wrong" with std::pairin C++03 but if I reimplement it naively, I don't have any problem with it, (using the same compiler gccand clang).

我不知道std::pairC++03有什么“错误”,但如果我天真地重新实现它,我没有任何问题,(使用相同的编译器gccclang)。

double a = 1.;
double b = 2.;
my::pair<double, double> p1(5., 6.);
my::pair<double&, double&> p2(a, b);
p2 = p1; // a == 5.

So a workaround could be to (1) reimplement pair(in a different namespace), or (2) specialize for std::pair<T&, T&>, or (3) simply use C++11 (where std::pairfor refs works out of the box)

因此,解决方法可能是 (1) 重新实现pair(在不同的命名空间中),或 (2) 专门用于std::pair<T&, T&>,或 (3) 简单地使用 C++11(其中std::pairfor refs 开箱即用)

(1) Here it is the naive implementation

(1) 这里是幼稚的实现

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);
}
}

(2) And here it is an specialization of std::pair(some people may complain that I am messing around overloading/specializing with the stdnamespace, but I think it is ok if it is to extend the capabilities of the class)

(2) 这里是一个专业化std::pair(有些人可能会抱怨我在重载/专业化std命名空间,但我认为如果它是扩展类的功能就可以了)

namespace std{
    template<class T1, class T2>
    struct pair<T1&, T2&>{
        typedef T1& first_type;    /// @c first_type is the first bound type
        typedef T2& second_type;   /// @c second_type is the second bound type
        first_type first;
        second_type second;
        pair(T1& t1, T2& 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;
        }
    };
}

Maybe I am missing something obvious, I can edit the answer if some obvious flaws, are pointed.

也许我遗漏了一些明显的东西,如果指出了一些明显的缺陷,我可以编辑答案。

回答by Zachary Kraus

I ended up solving a similar problem by just building a really simple structure. I didn't even worry about the assignment operator since the default one should work fine.

我最终通过构建一个非常简单的结构来解决类似的问题。我什至不担心赋值运算符,因为默认运算符应该可以正常工作。

template<class U, class V>
struct pair
{
pair(U & first, V & second): first(first), second(second) {}
U & first;
V & second;
}