C++ decltype与auto

C++ decltype与auto,c++,type-inference,C++,Type Inference,据我所知,decltype和auto都会试图找出某种东西的类型 如果我们定义: int foo () { return 34; } 那么这两种声明都是合法的: auto x = foo(); cout << x << endl; decltype(foo()) y = 13; cout << y << endl; auto x=foo(); coutdecltype给出传递给它的表达式的声明类型自动执行与模板类型推断相同的操作。因此,

据我所知,
decltype
auto
都会试图找出某种东西的类型

如果我们定义:

int foo () {
    return 34;
}
那么这两种声明都是合法的:

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

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

cout
decltype
给出传递给它的表达式的声明类型<代码>自动
执行与模板类型推断相同的操作。因此,例如,如果您有一个返回引用的函数,
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"
 }
#包括
int全局{};
int&foo()
{
回归全球;
}
int main()
{
decltype(foo())a=foo();//a是一个`int&`
auto b=foo();//b是一个`int`
b=2;
std::cout
auto
(在其推断类型的上下文中)仅限于定义具有初始值设定项的变量的类型。
decltype
是一个更广泛的构造,它将以额外信息为代价推断表达式的类型

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

auto x = foo();                           // more concise than `decltype(foo()) x`
std::vector<decltype(foo())> v{ foo() };  // cannot use `auto`
其中,
auto
只是一个前导,这样编译器就知道这是一个带有尾部返回类型的声明。虽然上面的示例可以简单地转换为旧式,但在泛型编程中它很有用:

template <typename T, typename U>
auto sum( T t, U u ) -> decltype(t+u)
模板
自动求和(T,U)->数据类型(T+U)

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

通常,如果要初始化的变量需要类型,则最好使用autodecltype来定义非变量的类型,例如返回类型。

修改@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;

}
#包括
int global=0;
int&foo()
{
回归全球;
}
int main()
{
decltype(foo())a=foo();//a是一个`int&`
auto b=foo();//b是一个`int`
b=2;

std::cout@JesseGood在提问之前,我读了这篇文章,想找一个更清晰的解释类似的问题:[1]:[2]:@JamesLeonard:好吧,我不知道更好的解释。Scott Meyers在youtube.com/watch?v=wQxj20X tIU&t=1468s上解释得很清楚
#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;

}