Bonjour,

Actuellement, dans std::unique_ptr<T, Deleter>, on a des fonctions constantes qui permettent de modifier la donnée pointée de type T :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
pointer get() const;
pointer operator->() const;
typename std::add_lvalue_reference<T>::type operator*() const;
avec pointer qui correspond à std::remove_reference<Deleter>::type::pointer si ce type existe, T* sinon.

Pourquoi std::unique_ptr a-t-il été conçu ainsi et pas comme ci-dessous ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<class T, class Deleter = std::default_delete<T>>
class unique_ptr
{
private:
    typedef typename std::add_const<T>::type const_T;
    // ...
public:
    typedef T&       reference;
    typedef const_T& const_reference;
    typedef T*       pointer;
    typedef const_T* const_pointer;
    pointer         get();
    const_pointer   get() const;
    pointer         operator->();
    const_pointer   operator->() const;
    reference       operator*();
    const_reference operator*() const;
    // ...
};
Une partie de la réponse est que std::unique_ptr a été conçu pour remplacer entièrement std::auto_ptr, mais la même question s'applique à ce dernier.
Pourquoi std::auto_ptr<T> contient-il ces fonctions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
T* get()        const;
T* operator->() const;
T& operator*()  const;
au lieu des fonctions ci-dessous ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
T*       get();
const T* get()        const;
T*       operator->();
const T* operator->() const;
T&       operator*();
const T& operator*()  const;
Actuellement, pour propager const, on peut utiliser std::experimental::propagate_const.
Par exemple, sur la page de en.cppreference.com consacrée à PImpl, le pointeur intelligent utilisé est un std::experimental::propagate_const<std::unique_ptr<impl>>.

Mais à quoi ça sert de pouvoir ne pas propager const avec un std::unique_ptr ?

Pour l'instant, le seul cas où ça m'a servi, c'est quand j'ai utilisé un std::unique_ptr<ClasseMalCodee>ClasseMalCodee était une classe d'une bibliothèque externe où il manquait des const.