你能解释一下这三个功能签名之间的区别吗?为什么auto可以用作返回的数据类型而不是参数声明?
//auto f1(auto x) { return x; } not accepted
auto f1(int x) { return x; }
auto f2(double x) -> decltype(x) { return x; }
template <typename T>
T f3(T x) { return x; }
答案 0 :(得分:0)
f1
获取int
并返回int
。 (auto
在此处推断为int
,因为返回表达式x
的类型为int
。)f2
需要double
并返回double
。 (这使用尾随返回类型,其中decltype(x)
的评估结果为double
,因为x
的类型为double
。)f3
是一个模板,将使用分配给T
的给定参数类型进行实例化,因此它返回相同的类型。 (函数体必须使用给定类型T
进行编译才能实例化该函数。)为什么自动可以用作返回的数据类型而不是参数声明?
因为这是语言的定义方式。 auto
也不是数据类型,它是推断类型的占位符。
答案 1 :(得分:0)
auto
并不真正作为类型存在,在编译期间会被特定类型替换。因此,只有在编译器可以确定要使用的单个特定类型来代替auto
关键字时,才能使用它。它不能用作泛型的形式来生成函数的多个变体。
auto f1(auto x) { return x; } // not accepted
在这种情况下,auto
是什么类型的?它可能是任何东西。编译器无法决定将哪个类型放在那里以完成f1
的签名。不允许编译器制作模板等多种变体。
auto f1(int x) { return x; }
auto
可以推导为int
,一切都很好。
auto f2(double x) -> decltype(x) { return x; }
auto
可以推导为double
,一切都很好。
template <typename T> T f3(T x) { return x; }
f3
是模板化的,因此在您使用它之前它并不存在。当您使用它时,编译器将创建一个变体,其中T
是您当前使用的类型。
答案 2 :(得分:0)
C ++ 11中auto说明符的主要任务是推导 编译时的给定值的类型。
auto A = 12; // A deduced type is int
auto B = 4.3; // B deduced type is double
auto C = "hello"; // C deduced type is const char*
这些都是可以使用auto的有效案例,因为它可以很容易地找出给定值的类型。
这样的事情是非法的:
auto D;
因为没有给定值。
有了功能,没有任何改变。
void foo(auto var) { }
当编译器生成你的函数 foo 时,它完全不知道用 auto 代替什么类型。
相反,其他三个函数都是有效的,因为编译器能够识别类型。
你能解释一下这三个功能签名之间的区别吗?
<强> 1 强>
auto f1(int x) { return x; }
f1 的返回类型与返回值的类型相同 x
<强> 2 强>
auto f2(double x) -> decltype(x) { return x; }
f2 的返回类型取决于参数 x 的类型,因为我们使用的是所谓的 trailing return type < / p>
当返回必须从表达式
推导出的类型时,它特别有用template<typename T, typename U>
auto foo(T a, U b) -> decltype(a+b) { ... }
此处返回类型将是参数 a 和 b
之间的总和所生成的类型int a = 10
double b = 2.3
return type = int + double = double
char a = 'y';
char b = 'o';
return type = char + char = int
第3 强>
template <typename T>
T f3(T x) { return x; }
这里T只评估一种类型,参数和返回类型也是一样。
f3("hello");
此处 T 评估为 const char * ,因此参数 x 和返回类型将自动为const char *