c++11::std::decltype/declval

decltype ( 实体 )    (1)    (C++11 起)
decltype ( 表达式 )    (2)    (C++11 起)
若实参是其他类型为 T 的任何表达式,且
a) 若 表达式 的值类别为亡值,则 decltype 产生 T&&;
b) 若 表达式 的值类别为左值,则 decltype 产生 T&;
c) 若 表达式 的值类别为纯右值,则 decltype 产生 T。

int a;
double d;
float f;

decltype(a) aa;
cout << typeid(aa).name() << endl; //int
decltype(d) dd;
cout << typeid(dd).name() << endl;//double
decltype(f) ff;
cout << typeid(ff).name() << endl;//float


template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) // 返回类型依赖于模板形参
{                                     // C++14 开始可以推导返回类型
    return t+u;
}
decltype应用场景:decltype多应用在泛型编程之中
template<typename T> class
{
    typename T::iterator it;
    void func(T t)
    {
        it = t.begin();    //这里取它迭代器的首位置
    }
};

template<typename T> class
{
    typename T::const_iterator it;
    void func(T t)
    {
        it = t.begin();    //这里取它迭代器的首位置
    }
};

使用decltype,上面的代码可以写成
template<typename T> class
{
    decltype(T.begin()) it;
    void func(T t)
    {
        it = t.begin();    //这里取它迭代器的首位置
    }
};

实际上,标准库中有些类型都是通过decltype来定义的:
typedef decltype(nullptr) nullptr_t;
typedef decltype(sizeof(0)) size_t;
函数模板
std::declval (c++11 only)
template<typename T>
typename add_rvalue_reference<T>::type declval() noexcept;

功能描述:
返回一个类型的右值引用,不管是否有没有默认构造函数或该类型不可以创建对象。(可以用于抽象基类);
struct A {            
    virtual int value() = 0;
};

class B : public A {
    int val_;
public:
    B(int i, int j) :val_(i*j) {}
    int value() { return val_; }
};


int main(void)
{
    decltype(std::declval<A>().value()) a;  // => int a
    decltype(std::declval<B>().value()) b;  // => int b

    decltype(B(0, 0).value()) c;   
    cout << typeid(c).name() << endl; 

    a = b = B(10, 2).value();
    std::cout << a << std::endl;
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/osbreak/p/11077068.html