Search code examples
c++c++11templatestypedeftype-traits

How does 'std::add_const' work when I instantiate it with 'const int'?


The following code snippet comes from libstdc++'s implementation of std::add_const,

/// add_const
template<typename _Tp>
struct add_const
{ typedef _Tp const     type; };

If I use int to instantiate std::add_const, then I will get the following, and it makes sense.

struct add_const
{ typedef int const     type; };

But, If I use const int to instantiate std::add_const, then it seems to me that I will get the following:

struct add_const
{ typedef const int const     type; };

For the above code, I will get duplicate const and it is a syntax error.

May I ask if I have any knowledge of blind spots about that?

I searched for related questions but didn't find the answer I wanted.

I am not a native English speaker, so please correct me if my expression is unclear.


Solution

  • For the above code I will get duplicate const and it is a syntax error.[...] ?

    No, For the T as const int case, the type remains unchanged (ie. const int), even though you apply std::add_const on it. The standard ensures that redundant const qualifiers are ignored.

    That means, the following all end up in the same type: const int

    const const int
    const const const int
    const int const
    const int const const
    int const const
    int const const const
    // .. so on ...
    

    The same happens in the typedef std::add_const as well. From cppreference.com:

     template< class T > 
     struct add_const;  (2) (since C++11)
    

    Provides the member typedef type which is the same as T, except it has a cv-qualifier added (unless T is a function, a reference, or already has this cv-qualifier)

    You could have simply check it:

    #include <type_traits> 
    
    
    static_assert(
        std::is_same_v<std::add_const_t<int>, 
                       std::add_const_t<const int>>, "are not same!");  // passes