繁体   English   中英

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

[英]Proper support of volatile qualifier of member functions in STL

STL中成员函数的volatile限定的重载的不正确支持会阻止以通用方式使用容器,智能指针等。 说,我想声明一个包装器类,该类提供值语义并允许基础类型不完整:

#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;
}

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设计决策如此差的原因是什么? 为什么STL不正确支持volatile成员函数限定符? 是否使用了volatile成员函数限定符?

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

请记住,对象上的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那样一时兴起的东西。

“糟糕的设计决策”? 并不是的。 关键字是从C继承的,但是今天很少使用。 它没有被弃用,但主要用途是在简单的情况下。 内存映射的硬件将是一个很好的例子。 但是不会有内存映射的std::deque<>因此STL支持的意义不大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM