63

据我了解,两者都decltypeauto尝试找出事物的类型。

如果我们定义:

int foo () {
    return 34;
}

那么这两个声明都是合法的:

auto x = foo();
cout << x << endl;

decltype(foo()) y = 13;
cout << y << endl;

你能告诉我decltype和之间的主要区别auto是什么吗?

4

5 回答 5

60

decltype给出传递给它的表达式的声明类型. auto做与模板类型推导相同的事情。因此,例如,如果您有一个返回引用的函数,它auto仍然是一个值(您需要auto&获取一个引用),但decltype将是返回值的类型。

#include <iostream>
int global{};
int& foo()
{
   return global;
}

int main()
{
    decltype(foo()) a = foo(); //a is an `int&`
    auto b = foo(); //b is an `int`
    b = 2;

    std::cout << "a: " << a << '\n'; //prints "a: 0"
    std::cout << "b: " << b << '\n'; //prints "b: 2"

    std::cout << "---\n";
    decltype(foo()) c = foo(); //c is an `int&`
    c = 10;

    std::cout << "a: " << a << '\n'; //prints "a: 10"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    std::cout << "c: " << c << '\n'; //prints "c: 10"
 }

另请参阅 David Rodríguez 的回答,其中只有一个autodecltype是可能的。

于 2012-08-23T02:53:25.497 回答
43

auto(在它推断类型的上下文中)仅限于定义具有初始化程序的变量的类型。decltype是一个更广泛的构造,以额外信息为代价,将推断表达式的类型。

auto可以使用的情况下,它比 更简洁decltype,因为您不需要提供从中推断类型的表达式。

auto x = foo();                           // more concise than `decltype(foo()) x`
std::vector<decltype(foo())> v{ foo() };  // cannot use `auto`

当对函数使用尾随返回类型时,该关键字auto也用于完全不相关的上下文中:

auto foo() -> int;

只有auto一个领导者,以便编译器知道这是一个带有尾随返回类型的声明。虽然上面的示例可以轻松转换为旧样式,但在泛型编程中它很有用:

template <typename T, typename U>
auto sum( T t, U u ) -> decltype(t+u)

请注意,在这种情况下,auto不能用于定义返回类型。

于 2012-08-23T02:55:18.137 回答
1

修改@Mankarse 的示例代码,我认为一个更好的自爆:

#include <iostream>
int global = 0;
int& foo()
{
   return global;
}

int main()
{
    decltype(foo()) a = foo(); //a is an `int&`
    auto b = foo(); //b is an `int`
    b = 2;

    std::cout << "a: " << a << '\n'; //prints "a: 0"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    std::cout << "global: " << global << '\n'; //prints "global: 0"

    std::cout << "---\n";

    //a is an `int&`
    a = 10;

    std::cout << "a: " << a << '\n'; //prints "a: 10"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    std::cout << "global: " << global << '\n'; //prints "global: 10"

    return 0;

}
于 2020-01-30T03:21:16.007 回答
0

我认为 auto 是一个纯粹的简化功能,而 decltype 的主要目的是在基础库中启用复杂的元编程。然而,从语言技术的使用角度来看,它们之间的关系非常密切。

HOPL20 4.2.1 开始,Bjarne Stroustrup。

于 2021-11-29T09:45:02.047 回答
0

通常,如果您需要初始化变量的类型,请使用auto。当您需要非变量的类型(如返回类型)时,最好使用decltype 。

于 2016-07-07T12:13:42.937 回答