Improper support of volatile-qualified overloadings of member functions in STL prevents using of containers, smart pointers, etc in generic way. Say, I want to declare a wrapper class, that provides value semantics and allows incompleteness of underlying type:
#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;
}
Lack of appropriate volatile-qualified overloading of std::unqie_ptr::operator * ()
causes an error:
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.
The same story WRT std::container::push_back()
, size()
, etc.
It totally prevents a using of objects of STL (not involving const_cast
operator) in generic code, which uses volatile
member-function qualifier.
What is a reason of such poor STL design decision? Why volatile
member function qualifier not properly supported in STL?? Is volatile
member function qualifier depricated?