【问题标题】:How to pass an overloaded function pointer as an argument without resolving (C++03)如何在不解析的情况下将重载函数指针作为参数传递 (C++03)
【发布时间】:2016-03-02 22:29:06
【问题描述】:

我想将重载函数应用于结构的所有元素,如下所示:(下面的代码将无法编译)

#include <iostream>

typedef struct {
  float float_val;
  int int_val;
} NodeStatus;

template<typename T>
void ApplyToFields(NodeStatus *ns1, NodeStatus *ns2, void (*func)(T, T)) {
  func(ns1->float_val, ns2->float_val);
  func(ns1->int_val, ns2->int_val);
}

template<typename T>
void add_print(T a, T b) {
  std::cout << b + a << std::endl;
}

template<typename T>
void sub_print(T a, T b) {
  std::cout << b - a << std::endl;
}

int main() {
  NodeStatus ns1, ns2;
  ns1.float_val = 2.3;
  ns2.float_val = 25.3;
  ns1.int_val = 2;
  ns2.int_val = 20;
  ApplyToFields(&ns1, &ns2, add_print);
  ApplyToFields(&ns1, &ns2, sub_print);
}

我是来自 C 的 C++ 新手。经过一些研究,我意识到在 C++ 中传递函数指针可能不是正确的方法。我对实现相同目的的最佳方法感兴趣,而不是我提出的可能不可能的字面问题。遵循 C++03 的解决方案将是理想的。谢谢!

【问题讨论】:

    标签: c++ function templates pointers


    【解决方案1】:

    你可以创建一个函数对象来包装你的函数模板(或替换它):

    struct add_printer {
        template<typename T>
        void operator()(T a, T b) const {
            add_print(a, b);
        }
    };
    

    然后像这样使用它:

    ApplyToFields(&ns1, &ns2, add_printer());
    

    这将延迟重载解析,直到add_printeroperator()ApplyToFields 中使用时实际实例化。

    在 C++14 中,您可以使用多态 lambda: [](auto a, auto b) { add_print(a, b); } 与函数对象不同,它几乎可以在任何地方定义,而不仅仅是在命名空间范围内。

    【讨论】:

      【解决方案2】:

      使用您的代码,您必须指定您想要的重载:

      ApplyToFields(&ns1, &ns2, add_print<float>);
      ApplyToFields(&ns1, &ns2, sub_print<int>);
      

      ApplyToFields<float>(&ns1, &ns2, add_print);
      ApplyToFields<int>(&ns1, &ns2, sub_print);
      

      Demo

      你想要的是一个泛型函子

      template<typename F>
      void ApplyToFields(const NodeStatus &ns1, const NodeStatus &ns2, F func) {
        func(ns1.float_val, ns2.float_val);
        func(ns1.int_val, ns2.int_val);
      }
      
      struct add_print
      {
          template<typename T>
          void operator() (T a, T b) {
              std::cout << b + a << std::endl;
          }
      };
      

      Demo

      【讨论】:

      • 谢谢,我知道当我按照您的描述传递函数签名时,我可以解析函数签名,但我想在 ApplyToFields 函数中同时使用 float 和 int 版本。我不想在该函数内部解决重载问题。
      • 是的,泛型函子正是我想要的。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 2022-01-20
      • 2016-02-20
      • 2015-01-29
      • 2013-03-16
      相关资源
      最近更新 更多