std::is_const(3)

NAME
std::is_const - std::is_const

Synopsis
   Defined in header <type_traits>
   template< class T > (since C++11)
   struct is_const;
   std::is_const is a UnaryTypeTrait.
   If T is a const-qualified type (that is, const, or const volatile), provides the
   member constant value equal to true. For any other type, value is false.
   If the program adds specializations for std::is_const or std::is_const_v, the
   behavior is undefined.

Template parameters
   T - a type to check
   Helper variable template
   template< class T > (since C++17)
   inline constexpr bool is_const_v = is_const<T>::value; Inherited from std::integral_constant

Member constants
   value true if T is a const-qualified type, false otherwise
   [static] (public static member constant)

Member functions
   operator bool converts the object to bool, returns value
                 (public member function)
   operator() returns value
   (C++14) (public member function)

Member types
   Type Definition
   value_type bool
   type std::integral_constant<bool, value>

Notes
   If T is a reference type then is_const<T>::value is always false. The proper way to
   check a potentially-reference type for const-ness is to remove the reference:
   is_const<typename remove_reference<T>::type>.

Possible implementation
   template<class T> struct is_const : std::false_type {};
   template<class T> struct is_const<const T> : std::true_type {};

Example
// Run this code
 #include <type_traits>
 static_assert(std::is_same_v<const int*, int const*>,
     "Remember, const-ness binds tightly inside pointers.");
 static_assert(!std::is_const_v<int>);
 static_assert(std::is_const_v<const int>);
 static_assert(!std::is_const_v<int*>);
 static_assert(std::is_const_v<int* const>,
     "Because the pointer itself can't be changed but the int pointed at can.");
 static_assert(!std::is_const_v<const int*>,
     "Because the pointer itself can be changed but not the int pointed at.");
 static_assert(!std::is_const_v<const int&>);
 static_assert(std::is_const_v<std::remove_reference_t<const int&>>);
 struct S
 {
     void foo() const {}
     void bar() const {}
 };
 int main()
 {
     // A const member function is const in a different way:
     static_assert(!std::is_const_v<decltype(&S::foo)>,
         "Because &S::foo is a pointer.");
     using S_mem_fun_ptr = void(S::*)() const;
     S_mem_fun_ptr sfp = &S::foo;
     sfp = &S::bar; // OK, can be re-pointed
     static_assert(!std::is_const_v<decltype(sfp)>,
         "Because sfp is the same pointer type and thus can be re-pointed.");
     const S_mem_fun_ptr csfp = &S::foo;
     // csfp = &S::bar; // Error
     static_assert(std::is_const_v<decltype(csfp)>,
         "Because csfp cannot be re-pointed.");
 }

See also
   is_volatile checks if a type is volatile-qualified
   (C++11) (class template)
   as_const obtains a reference to const to its argument
   (C++17) (function template)