# std::add_cv, std::add_const, std::add_volatile

< cpp‎ | types

定义于头文件 `<type_traits>` |  |
template< class T > struct add_cv; | (1) | (C++11 起)
template< class T > struct add_const; | (2) | (C++11 起)
template< class T > struct add_volatile; | (3) | (C++11 起)

提供同 `T` 的成员 typedef `type` ，除了它拥有添加的 cv 限定符（除非 `T` 是函数、引用或已拥有 cv 限定符）。

1) 添加 const 和 volatile
2) 添加 const
3) 添加 volatile

添加此页面上描述的任何模板的特化的程序行为未定义。

### 成员类型

名称 | 定义
`type` | 带 cv 限定符的类型 `T`

### 辅助类型

template< class T > using add_cv_t = typename add_cv<T>::type; |  | (C++14 起)
template< class T > using add_const_t = typename add_const<T>::type; |  | (C++14 起)
template< class T > using add_volatile_t = typename add_volatile<T>::type; |  | (C++14 起)

### 可能的实现

    template<class T> struct add_cv { typedef const volatile T type; };

    template<class T> struct add_const { typedef const T type; };

    template<class T> struct add_volatile { typedef volatile T type; };

### 注解

这些变换特征能用于在模板实参推导中建立非推导语境：

    template<class T>
    void f(const T&, const T&);

    template<class T>
    void g(const T&, std::add_const_t<T>&);

    f(4.2, 0); // 错误：对 'T' 推导出冲突的类型
    g(4.2, 0); // OK ：调用 g<double>

### 示例

    #include <iostream>
    #include <type_traits>

    struct foo
    {
        void m() { std::cout << "Non-cv\n"; }
        void m() const { std::cout << "Const\n"; }
        void m() volatile { std::cout << "Volatile\n"; }
        void m() const volatile { std::cout << "Const-volatile\n"; }
    };

    int main()
    {
        foo{}.m();
        std::add_const<foo>::type{}.m();
        std::add_volatile<foo>::type{}.m();
        std::add_cv<foo>::type{}.m();
    }

输出：

    Non-cv
    Const
    Volatile
    Const-volatile

### 参阅

is_const (C++11) | 检查类型是否为 const 限定 (类模板)
is_volatile (C++11) | 检查类型是否为 volatile 限定 (类模板)
remove_cv remove_const remove_volatile (C++11)(C++11)(C++11) | 从给定类型移除 const 或/与 volatile 限定符 (类模板)
as_const (C++17) | 获得到其实参的 const 引用 (函数模板)