10

就在最近,我了解到您可以使用具有函数类型的类变量语法声明一个函数(包括方法):

using function_type = int (double);
// pre-C++11:
//typedef int function_type(double);

function_type fun_global;

struct methods
{
    static function_type mem_fun_static;
    function_type mem_fun_normal;
    virtual function_type mem_fun_virtual;
    virtual function_type mem_fun_abstract = 0;
};

在上面的代码中

  • fun_global是一个全局函数,
  • mem_fun_staticstatic成员函数,
  • mem_fun_normal是一种普通的方法,
  • mem_fun_virtual是一种virtual方法,
  • mem_fun_abstract是一种抽象方法。

double它们都采用类型和返回值的单个参数int- 就像function_type说的那样。

这些年来我都知道 C++ 而我不知道这一点 - 这种语言从未停止让我感到惊讶!顺便说一句 -这里有没有提到这个语法?我没看到这个...

然而,在探索这个对我来说新的特性时,我偶然发现了编译器之间的一些不一致。对于测试,我使用了以下编译器:

  • GCC 5.4.0 和 7.1.0,命令行:g++ -Wall -Wextra -pedantic -std=c++14
  • Clang 4.0.1,命令行:clang++ -Wall -Wextra -pedantic -std=c++14
  • MSVC 19.10.25019(VS 2017),命令行:cl /W4 /EHsc

在我运行两个 GCC 版本的测试中给出了相同的结果,所以我将它们称为 GCC。


= delete不一致

struct methods
{
    /* ... */
    function_type mem_fun_deleted = delete;
};
  • 海湾合作委员会:好的
  • 铿锵声:错误!

    Test.cpp:13:34: error: '= delete' is a function definition and must occur in a standalone declaration
            function_type mem_fun_deleted = delete;
                                            ^
    1 error generated.
    
  • MSVC:好的

= default不一致

struct methods
{
    /* ... */
    using assignment_type = methods& (methods const&);
    assignment_type operator= = default;
};
  • 海湾合作委员会:好的
  • 铿锵声:错误!

    Test.cpp:14:30: error: '= default' is a function definition and must occur in a standalone declaration
            assignment_type operator= = default;
                                        ^
    1 error generated.
    
  • MSVC:错误!

    Test.cpp(14): error C2206: 'methods::operator =': typedef cannot be used for function definition
    

内联定义不一致

struct methods
{
    /* ... */
    function_type mem_fun_inline { return 0; }
};
  • 海湾合作委员会:错误!

    Test.cpp:13:43: error: invalid initializer for member function ‘int methods::mem_fun_inline(double)’
      function_type mem_fun_inline { return 0; }
                                               ^
    Test.cpp:13:43: error: expected ‘;’ at end of member declaration
    
  • 铿锵声:错误!

    Test.cpp:13:33: error: expected expression
            function_type mem_fun_inline { return 0; }
                                           ^
    Test.cpp:7:8: error: missing '}' at end of definition of 'methods'
    struct methods
           ^
    /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++config.h:194:1: note: still within definition of 'methods' here
    namespace std
    ^
    2 errors generated.
    
  • MSVC:好的


问题

哪些编译器在这里?

此外,是否可以:

  1. 在内联定义中(仅由 MSVC 支持)以某种方式引用参数?
  2. 以某种方式使用function_type这些函数的也在定义(当在类之外完成时)。以下是可以的(所有编译器)

    struct methods
    {
        static function_type mem_fun_static;
        /* ... */
    };
    
    int methods::mem_fun_static(double) { return 0; }
    

    这并没有那么糟糕,因为更改function_type应该会导致函数定义处的编译错误(因为它将不再与声明匹配) - 但仍然有可能避免这种情况。

4

1 回答 1

4

§ 8.3.5 函数 [dcl.fct] p12 函数类型的 typedef 可用于声明函数,但不得用于定义函数。

因此,Clang 在所有情况下拒绝代码是正确的,而接受它的编译器是错误的。

(引文来自 N4618,但该规则永远是该语言的一部分)。

于 2017-07-13T09:12:50.437 回答