简体   繁体   中英

non-const lvalue reference type _normal_iterator<> cannot bind a temporary of type _normal iterator in gcc

In the last line of the below code I get an error: non-const lvalue reference type _normal_iterator<> cannot bind a temporary of type _normal iterator with gcc, but not with Visual studio. Any suggestions why are highly appreciated.

struct Hand {
    Hand() = default;
    explicit Hand(std::set<std::string> cards) : cards(std::move(cards)) {}
    auto begin() const { return cards.begin(); }
    auto end() const { return cards.end(); }
};

std::vector<Hand> player_hands(number_players);  // empty container

auto &hand_it = player_hands.begin(); 

begin does not return a reference. It returns an iterator, which is itself an object, by value. Therefore player_hands.begin(); is a temporary. Temporaries can not be bound to non-const lvalue references.

What you can do is either of the following:

auto hand_it = player_hands.begin(); 

const auto& hand_it = player_hands.begin(); 

auto&& hand_it = player_hands.begin(); 

What you should use is the first case. Although the lifetime of the temporary will be extended in the other two cases, there is no need to use references at all. The second case also limits the usability, because it makes the iterator const , making it impossible to eg hand_it++ .

The iterator object itself refers to an element of the container. There is no need for references. A reference to the container element is obtained from the iterator with the indirection operator: *hand_it

Visual C++ is non-compliant with the standard in allowing binding of temporaries to non-const lvalue references. You can use the /permissive- flag to make it compliant and issue an error message for this code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM