1

According to the documentation for multiset for instance see http://www.cplusplus.com/reference/set/multiset/insert/. It should be possible to insert a const value. In my example the multiset is a collection of pointers, but when I try to insert a const pointer I get an error.

template<typename Key>
struct node_key: public node_base {
     node_key(Key k): _key(k) {}
     virtual ~node_key() {}
     const Key& key() const { return _key;}
protected:
     Key _key;
     void _copy_key(node_key<Key> *n) const { n->_key=_key;}
};

template <typename Compare>
struct ptr_less_key {
    ptr_less_key() : _comp() {}
    virtual ~ptr_less_key() {}

    template <typename Pointer>
    bool operator()(const Pointer& a, const Pointer& b) const { return _comp(a->key(), b->key()); }
    Compare _comp;
};

int main() {
  typedef node_key<int>* keyp;
  std::multiset<keyp,ptr_less_key<std::less<int>>> x;
  node_key<int> k(5);
  const node_key<int> *p=&k;
  x.insert(p); //this fails
  return 0;
}
user2304458
  • 363
  • 1
  • 2
  • 11

2 Answers2

2

What you are currently doing: You are not trying to insert a const pointer, as you think you do, but a non-const pointer to a const element.

Change this

const node_key<int> *p=&k;

to this

node_key<int> *const p=&k;

to make the const keyword apply on the pointer rather than on what it points to.

sebrockm
  • 5,733
  • 2
  • 16
  • 39
1

Given

 struct node {
     void member();
     void const_member() const;
 };

consider the four declarations

 node*              pointer_to_node;
 const node*        pointer_to_const_node;
 node* const        const_pointer_to_node;
 const node* const  const_pointer_to_const_node;

There are two different aspects of constness: that of the object node and that of the pointer. The first two declare mutable pointers to either node or const node. A conversion from node* to const node* is allowed (and implicit), but not the other way around, as this would allow to modify a const node.

The second two declarations declare the respective pointers to be constant, i.e. these pointers cannot be modified (though the node pointed to by const_pointer_to_node can.

 pointer_to_node->member();                              // okay
 pointer_to_node->const_member();                        // okay
 pointer_to_node = new node;                             // okay
 pointer_to_node = const_pointer_to_node;                // okay
 pointer_to_node = pointer_to_const_node;                // ERROR

 pointer_to_const_node->member();                        // ERROR
 pointer_to_const_node->const_member();                  // okay
 pointer_to_const_node = new node;                       // okay
 pointer_to_const_node = pointer_to_node;                // okay
 pointer_to_const_node = const_pointer_to_node;          // okay
 pointer_to_const_node = const_pointer_to_const_node;    // okay

 const_pointer_to_node->member();                        // okay
 const_pointer_to_node->const_member();                  // okay
 const_pointer_to_node = new node;                       // ERROR
 const_pointer_to_node = const_pointer_to_node;          // ERROR
 const_pointer_to_node = pointer_to_const_node;          // ERROR

 const_pointer_to_const_node->member();                  // ERROR
 const_pointer_to_const_node->const_member();            // okay
 const_pointer_to_const_node = new node;                 // ERROR 
 const_pointer_to_const_node = const_pointer_to_node;    // ERROR 
 const_pointer_to_const_node = pointer_to_const_node;    // ERROR 
Walter
  • 44,150
  • 20
  • 113
  • 196