提问者:小点点

什么时候应该使用decltype(表达式)?


我理解为什么我们需要decltype(auto)以及它与auto的区别,但是我不知道为什么以及何时应该/需要使用decltype(expression)。 在cppreference上的所有示例中,我可以只使用decltype(auto),我检查了它。 提前感谢你的帮助。


共3个答案

匿名用户

我能想到的最简单的例子是:

void foo(int i) {
    for (decltype(i) j = 0; j < i; ++j) 
        ...
}

在这里,索引j自动具有与上限i相同的类型。

lambda表达式提供了另一个示例:

[](auto i) {
    for (decltype(i) j = 0; j < i; ++j) 
        ...    
}

匿名用户

但我无法知道为什么和何时应该/需要使用decltype(expression)

在C++11中,您可以使用尾随返回类型,但不能使用自动推导的返回类型。 例如:

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) { return t + u; }

C++14等价物为:

template<typename T, typename U>
decltype(auto) add(T t, U u) { return t + u; }

另一个用途是SFINAE,例如检测具有特定名称的成员函数的存在:

#include <iostream>

template<class T>
auto test_has_f(T* p) -> decltype(static_cast<void>(p->f()), std::true_type{}); // Cast to void to avoid user-defined operator,(), if any.

std::false_type test_has_f(void*);

template<class T>
using HasF = decltype(test_has_f(static_cast<T*>(0)));

struct A {};
struct B { void f(); };

int main() {
    std::cout << HasF<A>::value << '\n'; // Outputs 0.
    std::cout << HasF<B>::value << '\n'; // Outputs 1.
}

匿名用户

有时,您需要声明一个与另一个类型相关的类型,但又希望保持它的不可知论性:

struct foo
{
    std::vector<int> data;
    decltype(data)::iterator it;
};