Namespaces
Variants

std::experimental:: propagate_const

From cppreference.net
Определено в заголовке <experimental/propagate_const>
template < class T >
class propagate_const ;
(library fundamentals TS v2)

std::experimental::propagate_const является константно-распространяющей обёрткой для указателей и указатель-подобных объектов. Он рассматривает обёрнутый указатель как указатель на const при доступе через константный путь доступа, отсюда и название.

Класс удовлетворяет требованиям MoveConstructible и MoveAssignable если базовый указатель-подобный тип удовлетворяет соответствующему требованию, но propagate_const не является ни CopyConstructible ни CopyAssignable .

Требования к типу
-
T должен быть типом указателя на объект без cv-квалификаторов или типом класса, подобного указателю, без cv-квалификаторов, как указано ниже.

Содержание

Требования к классам, подобным указателям

Если T является типом класса, он должен удовлетворять требованиям данного подраздела.

Дано

  • t , изменяемое lvalue-выражение типа T ,
  • ct , lvalue типа const T , обозначающее тот же объект, что и t (эквивалентно std:: as_const ( t ) начиная с C++17),
  • element_type , тип объекта.

Следующие выражения должны быть корректными и иметь указанные эффекты:

Выражение Тип возвращаемого значения Предусловия Операционная семантика
t. get ( ) element_type *
ct. get ( ) element_type * или const element_type * t. get ( ) == ct. get ( )
* t element_type & t. get ( ) ! = nullptr * t ссылается на тот же объект, что и * ( t. get ( ) )
* ct element_type & или const element_type & ct. get ( ) ! = nullptr * ct ссылается на тот же объект, что и * ( ct. get ( ) )
t. operator - > ( ) element_type * t. get ( ) ! = nullptr t. operator - > ( ) == t. get ( )
ct. operator - > ( ) element_type * или const element_type * ct. get ( ) ! = nullptr ct. operator - > ( ) == ct. get ( )
( bool ) t bool ( bool ) t эквивалентно t. get ( ) ! = nullptr
( bool ) ct bool ( bool ) ct эквивалентно ct. get ( ) ! = nullptr

Кроме того, T и const T должны быть контекстно преобразуемы в bool .

Кроме того, если T неявно преобразуется в element_type * , тогда ( element_type * ) t должно быть равно t. get ( ) . Аналогично, если const T неявно преобразуется в const element_type * , тогда ( const element_type * ) ct должно быть равно ct. get ( ) .

Типы членов

Тип члена Определение
element_type std:: remove_reference_t < decltype ( * std:: declval < T & > ( ) ) > , тип объекта, на который указывает T

Функции-члены

создает новый propagate_const
(public member function)
(destructor)
(implicitly declared)
уничтожает объект propagate_const , удаляя содержащийся указатель
(public member function)
присваивает объект propagate_const
(public member function)
обменивает обернутый указатель
(public member function)
Наблюдатели
возвращает указатель на объект, на который указывает обернутый указатель
(public member function)
проверяет, является ли обернутый указатель нулевым
(public member function)
разыменовывает обернутый указатель
(public member function)
неявная функция преобразования в указатель
(public member function)

Функции, не являющиеся членами класса

сравнивает с другим propagate_const , другим указателем, или с nullptr
(шаблон функции)
специализирует алгоритм swap
(шаблон функции)
получает ссылку на обернутый указатель-подобный объект
(шаблон функции)

Вспомогательные классы

поддержка хеширования для propagate_const
(специализация шаблона класса)
специализации стандартных функциональных объектов сравнения для propagate_const
(специализация шаблона класса)

Пример

#include <experimental/propagate_const>
#include <iostream>
#include <memory>
struct X
{
    void g() const { std::cout << "X::g (const)\n"; }
    void g() { std::cout << "X::g (non-const)\n"; }
};
struct Y
{
    Y() : m_propConstX(std::make_unique<X>()), m_autoPtrX(std::make_unique<X>()) {}
    void f() const
    {
        std::cout << "Y::f (const)\n";
        m_propConstX->g();
        m_autoPtrX->g();
    }
    void f()
    {
        std::cout << "Y::f (non-const)\n";
        m_propConstX->g();
        m_autoPtrX->g();
    }
    std::experimental::propagate_const<std::unique_ptr<X>> m_propConstX;
    std::unique_ptr<X> m_autoPtrX;
};
int main()
{
    Y y;
    y.f();
    const Y cy;
    cy.f();
}

Вывод:

Y::f (non-const)
X::g (non-const)
X::g (non-const)
Y::f (const)
X::g (const)
X::g (non-const)

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, являющиеся дефектными, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 3136 LFTSv2 бессмысленные T такие как int * const , void * , или const PtrLike были разрешены запрещены