Ibrahim Quraish
Ibrahim Quraish

Reputation: 4095

Declaring a C++ std::set iterator

The below program compiles fine if I comment the line insert(s, 10);

#include <iostream>
#include <iterator>
#include <set>

using namespace std;

template <class T>
void insert(std::set<T>& _s, const T& t) {
    typename std::set<T>::const_iterator i = _s.insert(t);
}

int main() {
    std::set<int> s;
    // insert<int>(s, 10); // line No: 14
}

But if I uncomment the line no 14, then I am getting the error as:

set.cpp:9:54: error: conversion from ‘std::pair<std::_Rb_tree_const_iterator<int>, bool>’ to non-scalar type ‘std::set::const_iterator’ requested

Upvotes: 0

Views: 1689

Answers (4)

user2628229
user2628229

Reputation: 269

std::set::insert used here is returning a pair, but its being assigned to a const_iterator

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361472

The overload ofinsert which you are using, returns pair, not const_iterator:

std::pair<typename std::set<T>::iterator,bool> pair = _s.insert(t);

That is ugly, isn't it? Use auto (if you're using C++11):

auto pair = _s.insert(t);

Cute, isn't?

BTW, why does it return std::pair instead of iterator?

Because insert might not add the item to set if it already exists. The pair.second tells you whether the element is inserted or it already exists — true means inserted, false means not inserted. The pair.first is the iterator which tells you the position where the element is found or inserted.

Upvotes: 8

Pierre Fourgeaud
Pierre Fourgeaud

Reputation: 14510

When you are using insert like it, it uses this overload :

pair<iterator,bool> insert (const value_type& val);

As you can see, it returns a pair and you are trying to get a std::set<T>::const_iterator.

You can fix it by doing :

 std::pair<typename std::set<T>::iterator,bool> ret = _s.insert(t);

(Like Nawaz is saying in his post, try to use auto instead)


The only overload that return an iterator is :

iterator insert (iterator position, const value_type& val);

Cf: http://en.cppreference.com/w/cpp/container/set/insert

Upvotes: 1

Graham Griffiths
Graham Griffiths

Reputation: 2216

yes, std::set::insert returns a pair as per the docs :

http://www.cplusplus.com/reference/set/set/insert/

so you can't assign the result to a const_iterator. The extra boolean is to tell you whether the insert succeeded, or if it failed because the value was already in the set.

Upvotes: 0

Related Questions