正确支持 STL 中成员函数的 volatile 限定符

Proper support of volatile qualifier of member functions in STL

STLvolatile-qualified 成员函数重载的不正确支持阻止以通用方式使用容器、智能指针等。比如说,我想声明一个包装器 class,它提供值语义并允许基础类型的不完整性:

#include <type_traits>
#include <utility>
#include <memory>

template< typename type >
struct recursive_wrapper
{

    using value_type = type;

    template< typename ...arguments >
    recursive_wrapper(arguments &&... _arguments)
        : storage_(std::make_unique< type >(std::forward< arguments >(_arguments)...))
    { ; }

    operator type & () & noexcept
    {
        return *storage_;
    }

    operator type const & () const & noexcept
    {
        return *storage_;
    }

    operator type && () && noexcept
    {
        return std::move(*storage_);
    }

    operator type const && () const && noexcept
    {
        return std::move(*storage_);
    }

    operator volatile type & () volatile & noexcept
    {
        return *storage_;
    }

    operator volatile type const & () volatile const & noexcept
    {
        return *storage_;
    }

    operator volatile type && () volatile && noexcept
    {
        return std::move(*storage_);
    }

    operator volatile type const && () volatile const && noexcept
    {
        return std::move(*storage_);
    }

private :

    std::unique_ptr< type > storage_;

};

// file:main.cpp
#include <iostream>
#include <vector>

#include <cstdlib>

int
main()
{
    struct A;
    struct B { recursive_wrapper< A > a; };
    struct A { std::vector< B > b; };
    { // basic usage
        B b; 
        A & a = b.a; // OK
        static_cast< void >(a);
    }
    // let's add cv-qualifiers
    {
        volatile B b; 
        volatile A & a = b.a; // error!
        static_cast< void >(a);
    }
    return EXIT_SUCCESS;
}

缺少适当的 volatile-qualified 重载 std::unqie_ptr::operator * () 导致错误:

main.cpp:38:16: error: indirection requires pointer operand ('volatile std::unique_ptr<A>' invalid)
        return *storage_;
               ^~~~~~~~~
main.cpp:83:30: note: in instantiation of member function 'recursive_wrapper<A>::operator volatile A &' requested here
            volatile A & a = b.a;
                             ^
1 error generated.

相同的故事 WRT std::container::push_back()size()

它完全阻止了在使用 volatile 成员函数限定符的通用代码中使用 STL 的对象(不涉及 const_cast 运算符)。

如此糟糕的 STL 设计决策的原因是什么?为什么 volatile 成员函数限定符在 STL 中没有得到正确支持? volatile 成员函数限定符是否被删除?

"Poor design decision"?并不真地。该关键字是从 C 继承而来的,但在今天已经很少用到它了。它并没有被积极弃用,但它的主要用途是在简单的情况下。内存映射硬件就是一个很好的例子。但是不会有内存映射 std::deque<> 所以 STL 对此的支持没有什么意义。

这是一个非常好的决定。这是因为对于大多数类型而言,波动性 完全错误

请记住,对象上的 volatile 意味着 对象的字段可以自发变异
考虑以下情况,并假设系统保证在任何给定时刻,beginend 将指向同一内存块:

template<class T>
class vector
{
    T *begin;
    T *end;
    vector(vector const volatile &other) : begin(other.begin), end(other.end) { ... }
};

原来vector::vector(vector const volatile &)错误的,因为不能保证同时读取beginend
因此,它创建的副本可能有 beginend 不同步,即使原始副本完全没问题。

我想这应该足以让你明白为什么 volatile 很少被使用了。
它的使用原因与您可能期望使用的原因相同(即原子)。
它的用例是完全不同和不常见的,它不是你随心所欲地使用 const.

的方式。