C++ 11: conversion const int* to int* using unordered_set::push

The key of the set is declared as being a pointer-to-int, an int*. But this:

void push( const B& b )
{
    set.insert( &b.x );
}

is passing the address of a constant int, an int const*, hence the compiler error.

Removing the const from the argument would resolve the compiler error, as would making the key type an int const*, but both these solutions would:

  • permit some other part of the program, with non-const access to a B instance that was passed to push(), to change a value of one of the keys within the set and break the set invariant:

    A a;
    
    B b1{17, 22};
    B b2{30, 22};
    
    a.push(b1);
    a.push(b2);
    
    b1.x = 30;  // set no longer contains unique keys.
    
  • introduce a dependency of the set on the lifetime of the object referenced by b:

    A a;
    a.push({14, 23}); // a now contains a dangling pointer.
    

The safest solution is to store an int as the key, see http://ideone.com/KrykZw for online demo (thanks to bitmask for comment).


Possible solutions:

  1. Dynamically copy b.x. Or,
  2. Use int const* as the key. Or preferably (avoiding explicit dynamic allocation),
  3. Use int as the key, instead of an int* (see http://ideone.com/KrykZw)

Leave a Comment