Outils pour utilisateurs

Outils du site


prog:cpp:propagate_const

Ceci est une ancienne révision du document !


Problématique de base

Soit une classe Y qui possède un membre de type classe X. L'objectif est que, si une méthode const de Y est appelée, il ne sera possible d'appeler que les méthodes const de X.

Soit la classe commune X :

#include <iostream>
 
struct X
{
  void g() const { std::cout << "g (const)\n"; }
  void g() { std::cout << "g (non-const)\n"; }
};

et le programme commun :

int main()
{
  Y y;
  y.f();
 
  const Y cy;
  cy.f();
}

Objet

struct Y
{
  Y() = default;
 
  void f() const
  {
    std::cout << "f (const)\n";
    m_ptrX.g();
  }
 
  void f()
  {
    std::cout << "f (non-const)\n";
    m_ptrX.g();
  }
 
  X m_ptrX;
};

Rendu :

f (non-const)
g (non-const)
f (const)
g (const)

Pointeur

struct Y
{
  Y() : m_ptrX(new X()) {};
 
  void f() const {
    std::cout << "f (const)\n";
    m_ptrX->g();
  }
 
  void f() {
    std::cout << "f (non-const)\n";
    m_ptrX->g();
  }
 
  X* m_ptrX;
};

Rendu :

f (non-const)
g (non-const)
f (const)
g (non-const)

Référence

struct Y
{
  Y() : m_ptrX(m_X) {};
 
  void f() const {
    std::cout << "f (const)\n";
    m_ptrX.g();
  }
 
  void f() {
    std::cout << "f (non-const)\n";
    m_ptrX.g();
  }
 
  X& m_ptrX;
  X m_X;
};

Rendu :

f (non-const)
g (non-const)
f (const)
g (non-const)

propagate_const

Pointeur

Fonctionne avec X*, std::unique_ptr et std::shared_ptr.

#include <https://raw.githubusercontent.com/jbcoe/propagate_const/refs/heads/master/propagate_const.h>
 
struct Y {
  Y() : m_ptrX(new X()) {};
 
  void f() const {
    std::cout << "f (const)\n";
    m_ptrX->g();
  }
 
  void f() {
    std::cout << "f (non-const)\n";
    m_ptrX->g();
  }
 
   std::experimental::propagate_const<X*> m_ptrX;
};

Rendu :

f (non-const)
g (non-const)
f (const)
g (const)

Référence

Impossible.

indirect_value

indirect_value est un std::unique_ptr avec la préservation de const. Il n'y a pas d'équivalent avec shared_ptr / pointeur / référence.

Pointeur

#include <https://raw.githubusercontent.com/jbcoe/indirect_value/refs/heads/main/indirect_value.h>
 
struct Y {
  Y() : m_ptrX(isocpp_p1950::make_indirect_value<X>()) {};
 
  void f() const {
    std::cout << "f (const)\n";
    m_ptrX->g();
  }
 
  void f() {
    std::cout << "f (non-const)\n";
    m_ptrX->g();
  }
 
  isocpp_p1950::indirect_value<X> m_ptrX;
};

Rendu :

f (non-const)
g (non-const)
f (const)
g (const)

value_types

Référence

#include <https://raw.githubusercontent.com/jbcoe/value_types/refs/heads/main/polymorphic.h>
 
struct Y
{
  Y() : m_ptrX(xyz::polymorphic<X>()) {};
 
  void f() const {
    std::cout << "f (const)\n";
    m_ptrX->g();
  }
 
  void f() {
    std::cout << "f (non-const)\n";
    m_ptrX->g();
  }
 
  xyz::polymorphic<X> m_ptrX;
};

Rendu :

f (non-const)
g (non-const)
f (const)
g (const)

Pointeur

#include <https://raw.githubusercontent.com/jbcoe/value_types/refs/heads/main/polymorphic.h>
 
struct Y
{
  Y() : m_ptrX(xyz::polymorphic<X>()) {};
 
  void f() const {
    std::cout << "f (const)\n";
    m_ptrX->g();
  }
 
  void f() {
    std::cout << "f (non-const)\n";
    m_ptrX->g();
  }
 
  xyz::polymorphic<X> m_ptrX;
};

Rendu :

f (non-const)
g (non-const)
f (const)
g (const)
prog/cpp/propagate_const.1751821113.txt.gz · Dernière modification : de root