decltype和declval

Last Updated: 2023-09-27 12:06:24 Wednesday

-- TOC --

decltype

decltype就像sizeof,编译器内置的operator,在编译期起作用!常见的应用场景,就是提取某个变量的type,或者container的value_type。

#include <vector>
#include <iostream>
#include <utility>
using namespace std;

int main(){
    pair<int,int> pii;
    vector<decltype(pii)> vpii;
    cout << typeid(pii).name() << endl;
    cout << typeid(decltype(vpii)::value_type).name() << endl;
    return 0;
}

可以看到,打印出来的两个type是一样的。vpii这个container的value_type,就是pii的type。这样写代码有个好处,重构的时候会比较轻松,只要修改pii的type,其它代码位置的type就跟随着进行调整,不需要修改那么多位置的代码。不用将相同的type不断地重复,而是采用C++类型推导的方式。

declval

而declval是一个标准库中的template function。

declval可以用如下定义:

template<typename T>
inline constexpr bool _always_false_v { false };


// declval is a template function,
// decltype is an operator,like sizeof.
// They are all used in compile time deduction.
template<typename T>
std::add_rvalue_reference_t<T> declval() noexcept{
    static_assert(_always_false_v<T>,
                  "declval<T>() can only be used in compile time.");
}

在编译期类型推导过程中,如果出现declval,编译器并不会去执行这个函数,而仅仅是使用其返回值,也就是原地构造一个T&&出来。

Converts any type T to a reference type, making it possible to use member functions in the operand of the decltype specifier without the need to go through constructors. 原地构造,还无需经过ctor。

配合decltype,就可以在编译期得到T成员函数的返回值类型。如果获得失败,还可以进一步得到T没有某个成员函数的信息,利用SFINAE机制,实现编译期接口选择。

注意:使用decltypedeclval<T>,都要有()

本文链接:https://cs.pynote.net/sf/c/cpp/202301253/

-- EOF --

-- MORE --