是否可以在带有初始化的函数指针声明中使用 `auto` 关键字作为 return 类型?
Is it possible to use the `auto` keyword as a return type in a function pointer declaration with initialization?
下面的代码compiles successfully both with clang++ 3.8.0 and g++ 7.2.0(编译标志是-std=c++14 -O0 -Wall -Wextra -Werror -pedantic-errors
):
#include <iostream>
int foo_int(int)
{
std::cout << "int foo(int)" << std::endl;
return 0;
}
void foo_void(int)
{
std::cout << "void foo(int)" << std::endl;
}
auto foo_auto_int(int)
{
std::cout << "auto foo(int), auto == int" << std::endl;
return 0;
}
auto foo_auto_void(int)
{
std::cout << "auto foo(int), auto == void" << std::endl;
return void();
}
int main()
{
auto (*fi)(int) = foo_int;
auto (*fv)(int) = foo_void;
auto (*fai)(int) = foo_auto_int;
auto (*fav)(int) = foo_auto_void;
(void)fi(0);
fv(0);
(void)fai(0);
fav(0);
}
它是有效的 C++ 代码吗?
请注意 decltype(auto)
是 rejected both by clang++ and g++ in the same situation。
编译器运行正常。
The auto
and decltype(auto)
type-specifiers are used to designate a placeholder type that will be replaced later by deduction from an initializer.
[...]
auto
or decltype(auto)
shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl-specifier-seq shall be followed by one or more declarators, each of which shall be followed by a non-empty initializer.
也就是说 auto
和 decltype(auto)
只能用你在声明前面写的说明符来写(static
、virtual
等),用它们的类型是从紧随其后的 声明符 和 初始化程序 .
推导出来的
案例auto
声明符在auto (*fi)(int) = foo_int;
的情况下是(*fi)(int)
,其形式为
( ptr-operator declarator-id ) ( parameter-declaration-clause )
因此 auto (*fi)(int) = foo_int;
是有效的,前提是 deduction succeeds 确实如此。其他几个也一样。
案例decltype(auto)
来自 [dcl.spec.auto.deduct],给定类型 T
包含占位符类型
If the placeholder is the decltype(auto)
type-specifier, T
shall be the placeholder alone.
这意味着添加任何其他内容都是非法的
int i;
decltype(auto)* p = &i; // error, declared type is not plain decltype(auto)
因此decltype(auto) (*fi)(int) = foo_int;
是非法的。
下面的代码compiles successfully both with clang++ 3.8.0 and g++ 7.2.0(编译标志是-std=c++14 -O0 -Wall -Wextra -Werror -pedantic-errors
):
#include <iostream>
int foo_int(int)
{
std::cout << "int foo(int)" << std::endl;
return 0;
}
void foo_void(int)
{
std::cout << "void foo(int)" << std::endl;
}
auto foo_auto_int(int)
{
std::cout << "auto foo(int), auto == int" << std::endl;
return 0;
}
auto foo_auto_void(int)
{
std::cout << "auto foo(int), auto == void" << std::endl;
return void();
}
int main()
{
auto (*fi)(int) = foo_int;
auto (*fv)(int) = foo_void;
auto (*fai)(int) = foo_auto_int;
auto (*fav)(int) = foo_auto_void;
(void)fi(0);
fv(0);
(void)fai(0);
fav(0);
}
它是有效的 C++ 代码吗?
请注意 decltype(auto)
是 rejected both by clang++ and g++ in the same situation。
编译器运行正常。
The
auto
anddecltype(auto)
type-specifiers are used to designate a placeholder type that will be replaced later by deduction from an initializer.[...]
auto
ordecltype(auto)
shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl-specifier-seq shall be followed by one or more declarators, each of which shall be followed by a non-empty initializer.
也就是说 auto
和 decltype(auto)
只能用你在声明前面写的说明符来写(static
、virtual
等),用它们的类型是从紧随其后的 声明符 和 初始化程序 .
案例auto
声明符在auto (*fi)(int) = foo_int;
的情况下是(*fi)(int)
,其形式为
( ptr-operator declarator-id ) ( parameter-declaration-clause )
因此 auto (*fi)(int) = foo_int;
是有效的,前提是 deduction succeeds 确实如此。其他几个也一样。
案例decltype(auto)
来自 [dcl.spec.auto.deduct],给定类型 T
包含占位符类型
If the placeholder is the
decltype(auto)
type-specifier,T
shall be the placeholder alone.
这意味着添加任何其他内容都是非法的
int i;
decltype(auto)* p = &i; // error, declared type is not plain decltype(auto)
因此decltype(auto) (*fi)(int) = foo_int;
是非法的。