decltype
和std::declval
在C++中都是用于类型推导的工具,但它们的使用方式和目的有所不同。
1.decltype: decltype
是一个类型推导关键字,它用于在编译时确定一个表达式或类型的类型。可以用它来获取一个变量、函数返回类型、或者任何表达式的类型,decltype`还可以用于模板编程,以推导模板参数的类型。decltype
的结果是一个类型,而不是一个值。例如
int x = 10;
decltype(x) y = 20; // y的类型是int
2.declval:
std::declval
是一个函数模板,它并不真正返回一个值,而是产生一个引用到指定类型的假设值。它通常与decltype
结合使用,以在不需要实际创建对象的情况下推导类型的值属性(例如,推导函数指针或成员函数指针的类型)。
std::declval
的主要用途是在不实际创建对象的情况下确定类型的某些属性,这在模板元编程中特别有用,因为有时可能需要知道一个类型的某些属性,但又不想或不能创建该类型的实例。
例如,如果想检查一个类型是否有某个成员函数,可以使用std::declval
和decltype
结合sizeof...
操作符来实现:
template<typename T>
struct has_begin_end
{
template<typename C> static constexpr auto check(C*)
-> typename std::enable_if<
std::is_same<decltype(std::declval<C&>().begin()), decltype(std::declval<C&>().end())>::value,
std::true_type
>::type;
template<typename> static constexpr std::false_type check(...);
static constexpr bool value = decltype(check<T>(nullptr))::value;
};
在这个例子中,std::declval
被用于在不实际创建T
类型对象的情况下检查begin
和end
成员函数是否存在且返回类型相同。
总的来说,decltype
和std::declval
都是强大的类型推导工具,但它们的用途和上下文有所不同。decltype
用于确定表达式或类型的类型,而std::declval
则用于在不需要实际创建对象的情况下确定类型的某些属性。