【问题标题】:Function pointer initialization with function declaration - is it possible?使用函数声明初始化函数指针 - 有可能吗?
【发布时间】:2019-07-19 11:45:41
【问题描述】:

是否可以在 C++ 中使用函数声明来初始化函数指针?我的意思是,像这样:

void (*pointer)(void) = &( void function(void) );

或者这个:

void (*pointer)(void) = void function(void);

【问题讨论】:

  • 我的建议是停止使用显式函数指针。使用auto 进行自动类型推断,或者如果您需要保存或传递“函数”,请使用std::function

标签: c++ pointers initialization declaration


【解决方案1】:

这几乎是可能的,你只需要颠倒顺序:先声明函数,然后用它的地址初始化指针:

void function(), (*pointer)() = &function;

[Live example]

但是,我认为这个丑陋、不可读的代码,并且从不建议实际使用它。所以,我的回答是:“这是可能的,但永远不应该这样做。” (我可以想象在某些涉及宏的情况下这是可以原谅的,但仅此而已)。

【讨论】:

  • 一般同意。除了在 C++ 中使用宏很少是可以原谅的,更不用说在一个中使用这样的结构了。
  • @Peter 在我们获得 C++ 中的元类之前,宏将用于样板消除和代码生成。我完全同意应谨慎使用它们,但仍将它们视为合法工具。
  • 我确实说“很少”,而不是“从不”
【解决方案2】:

不,因为 C++ 中的任何变量(包括函数指针)都必须使用 表达式 进行初始化,并且函数声明不是表达式。

您可能希望使用无捕获的 lambda 表达式:

void (*pointer)() = []{ std::cout << "hello world\n"; };

【讨论】:

    【解决方案3】:

    不,因为指针(包括函数指针)必须使用表达式初始化。函数声明不是表达式。

    但是,可以使用编译单元(也称为源文件)中先前声明的函数(或变量)来组合表达式

    void function();     //  declare the function, defined elsewhere
    
    void (*pointer)() = function;   //  function name in an expression is converted to a function pointer
    

    可以(出于可读性目的不推荐)将两者结合在一个声明中的多个变量中。

    void function(), (*pointer)() = function;
    

    【讨论】:

      【解决方案4】:

      初始化器可能不是声明。它没有任何意义。声明时已经指定了指针的类型。

      如果你声明了一个指针,当你必须给它赋值时想要初始化它。

      这是一个演示程序。它使用一个函数指针数组(更有趣)。

      #include <iostream>
      
      void f1()
      {
          std::cout << "Hello ";
      }
      
      void f2()
      {
          std::cout << "Roman Kwaśniewski";
      }
      
      void f3()
      {
          std::cout << '\n';
      }
      
      int main()
      {
          void ( *fp[] )() = { f1, f2, f3 };
      
          for ( auto &func : fp ) func();
      }
      

      程序输出是

      Hello Roman Kwaśniewski
      

      请注意,您不需要指定例如 &f2 作为初始化器,因为函数指示符会隐式转换为指针。

      虽然例如这个初始化也是正确的

          void ( *fp[] )() = { f1, %f2, f3 };
      

      和上一个是等价的。

      【讨论】:

        猜你喜欢
        • 2013-11-22
        • 2020-04-19
        • 2015-12-30
        • 1970-01-01
        • 2017-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多