是否可以在函数指针声明中使用`auto`关键字作为返回类型进行初始化?

问题描述 投票:15回答:1

以下代码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

c++ initialization language-lawyer function-pointers auto
1个回答
10
投票

编译器表现正常。

来自[dcl.spec.auto]

autodecltype(auto)类型说明符用于指定占位符类型,稍后将通过从初始化程序中进行推导来替换该占位符类型。

[...]

autodecltype(auto)应作为decl-specifier-seq中的decl-specifiers之一出现,而decl-specifier-seq后面应跟一个或多个声明符,每个声明符后面都应跟一个非空的初始值设定项。

这就是说autodecltype(auto)只能用你在声明前面写的说明符(staticvirtual等)编写,它们的类型是从紧跟在后面的声明符中用推导符推导出来的。

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类型

如果占位符是decltype(auto)类型说明符,则T应仅为占位符。

这意味着添加任何其他内容都是非法

int i;
decltype(auto)* p = &i;  // error, declared type is not plain decltype(auto)

因此decltype(auto) (*fi)(int) = foo_int;是非法的。

© www.soinside.com 2019 - 2024. All rights reserved.