Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between pair of consts and const pair

Tags:

c++

constants

In C++, what's the difference in behavior between std::pair<const T, const U> and const std::pair<T, U>?

like image 415
jleahy Avatar asked Jan 31 '13 16:01

jleahy


People also ask

What does STD pair do?

std::pair is a class template that provides a way to store two heterogeneous objects as a single unit. A pair is a specific case of a std::tuple with two elements.

Is const int the same as int const?

const int * And int const * are the same. const int * const And int const * const are the same. If you ever face confusion in reading such symbols, remember the Spiral rule: Start from the name of the variable and move clockwise to the next pointer or type.

How do you declare and initialize a pair in C++?

Another way to initialize a pair is by using the make_pair() function. g2 = make_pair(1, 'a'); Another valid syntax to declare pair is: g2 = {1, 'a'};

What does const int mean in C++?

int const* is pointer to constant integer This means that the variable being declared is a pointer, pointing to a constant integer. Effectively, this implies that the pointer is pointing to a value that shouldn't be changed.


1 Answers

The core difference is that they are different unrelated types (with some implicit conversions among them).

void f(std::pair<std::string,std::string> const &);
std::string longstring();
int main() {
   std::pair<const std::string,const std::string> pc
        = std::make_pair(longstring(),longstring());
   f(pc);
   const std::pair<std::string,std::string> cp
        = std::make_pair(longstring(),longstring());
   f(cp); 
}

While there are implicit conversions that allow f(pc) to compile, that line involves a conversion, and the conversion involves making a copy of the longstring()s. On the other hand, the call f(cp) only binds a constant reference to the existing pair as the type matches, not requiring any copies.

The fact that the compiler let's you write similar code, does not mean that the code is compiled to do the same thing. This is particularly true for types with implicit conversions, as is the case of std::pair

This is a common pitfall when writing functors to operate on elements stored in maps, where a mismatch on the argument of the functor will cause unnecessary copying of the object data:

std::map<int,std::string> m = create_map();
std::for_each(m.begin(),m.end(),
              [](std::pair<int,std::string> const &r) { 
                    std::cout << r.second << " ";
              });

The lambda above does not have the correct type of argument (std::pair<int,std::string vs. std::pair<const int,std::string>) and that causes each call to copy both the index and the value (i.e. all strings will be copied, to an std::pair<int,std::string> and then a reference bound for the argument to the lambda). The simple recommendation in this case would be to use std::map<int,std::string>::value_type const & for the argument type.

like image 71
David Rodríguez - dribeas Avatar answered Oct 09 '22 05:10

David Rodríguez - dribeas