Const temporary from template type and why use std::add_const?

后端 未结 2 1425
一向
一向 2021-01-05 00:23

The following code is excerpted from cppreference.com.

#include 
#include 

struct foo
{
    void m() { std::cout <<          


        
2条回答
  •  失恋的感觉
    2021-01-05 00:42

    This appears to be a bug with MSVC. Using an expression of the form T() (which is an explicit type conversion, as far as the standard is concerned) results in a prvalue of the specified type.

    The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, which is value-initialized

    It is only with non-class types that the const would be ignored, due to a rule that non-class prvalues cannot have cv-qualified types:

    Class prvalues can have cv-qualified types; non-class prvalues always have cv-unqualified types.

    So the temporary object created by T() here should be const and should therefore call the const member function.

    As for when and why you would use std::add_const, we can take a look at the reason it was included in the proposal. It states that the add_const, add_volatile, add_cv, add_pointer, and add_reference type traits were removed from the proposal but then reinstated after complaints from users of Boost.

    The rationale is that these templates are all used as compile time functors which transform one type to another [...]

    The example given is:

    // transforms 'tuple'
    // to 'tuple'
    template< typename Tuple >
    struct tuple_of_refs
    {
       // transform tuple element types
       typedef typename mpl::transform<
          typename Tuple::elements,
          add_reference< add_const<_1> > // here!
       >::type refs;
       typedef typename tuple_from_sequence::type type;
    };
    
    template< typename Tuple >
    typename tuple_of_refs::type
    tuple_ref(Tuple const& t)
    {
        return typename tuple_of_refs::type(t);
    }
    

    You can think of mpl::transform as taking the compile-time metaprogramming equivalent to a function pointer as its second template argument - add_reference> is applied to each of the types in Tuple::elements. This simply couldn't be expressed using const.

提交回复
热议问题