使用函数类型语法声明成员函数

时间:2017-07-13 08:03:49

标签: c++ g++ clang++ cl

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

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_virtualvirtual方法,
  • mem_fun_abstract是一种抽象方法。

所有这些都采用double类型的单个参数并返回int值 - 就像function_type所说的那样。

这些年来,我知道C ++并且我不知道这个 - 这种语言永远不会让我感到惊讶!顺便说一下 - 这个语法是在here的任何地方提到的吗?我没有看到这个...

然而,在探索这个新功能时,我偶然发现编译器之间存在一些不一致之处。对于测试,我使用了以下编译器:

  • 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;
};
  • 海湾合作委员会:好的
  • Clang:错误!

    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;
};
  • 海湾合作委员会:好的
  • Clang:错误!

    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
    
  • Clang:错误!

    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的更改应该导致函数定义中的编译错误(因为它将不再匹配声明),所以并没有那么糟糕 - 但是仍然可以避免这种情况。

    < / LI>

1 个答案:

答案 0 :(得分:4)

  

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

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

(报价来自N4618,但规则是永远的语言的一部分)。