对模板参数中函数的常量引用

const reference to a function in a template parameter?

本文关键字:常量 引用 函数 参数      更新时间:2023-10-16

如何声明我想要一个常量函数引用(在模板中)参数)?例如,

template< bool (&func)(int arg) >
void foo(int stuff);

但是康斯特?

更具体地说,如果我尝试使用 icpc 编译以下内容:

template<bool (&func)(int arg)>
bool id(int arg) {
  return func(arg);
}
class Foo {
 public:
  Foo() {};
  virtual ~Foo() {};
  bool bar(int arg) { return true; }
  bool bar2(int arg) {
    return id<bar>(arg);
  };
};
int main() {
  return 0;
}

我得到

$ icpc foo.cpp
foo.cpp(12): error: no instance of function template "id" matches the argument list
            argument types are: (int)
      return id<bar>(arg);
             ^
compilation aborted for foo.cpp (code 2)

或者,有了g++,我得到

$ g++ foo.cpp
foo.cpp: In member function ‘bool Foo::bar2(int)’:
foo.cpp:13:23: error: no matching function for call to ‘id(int&)’
     return id<bar>(arg);
                       ^
foo.cpp:13:23: note: candidate is:
foo.cpp:2:6: note: template<bool (& func)(int)> bool id(int)
 bool id(int arg) {
      ^
foo.cpp:2:6: note:   template argument deduction/substitution failed:
foo.cpp:13:23: error: could not convert template argument ‘Foo::bar’ to ‘bool (&)(int)’
     return id<bar>(arg);
                       ^

但是,如果我将栏移动到顶层,例如

template<bool (&func)(int arg)>
bool id(int arg) {
  return func(arg);
}
bool bar(int arg) { return true; }
class Foo {
 public:
  Foo() {};
  virtual ~Foo() {};
  bool bar2(int arg) {
    return id<bar>(arg);
  };
};
int main() {
  return 0;
}

它编译得很好。为什么会发生这种情况,如何在不使 bar 成为全局的情况下修复它?

注意:在我的原始代码中,我收到"(非常量限定)无法使用类型值初始化"错误:(带icpc

CollisionWorld.cpp(73): error: a reference of type "bool (&)(const Line &, vec_dimension={double}, vec_dimension={double}, vec_dimension={double}, vec_dimension={double})" (not const-qualified) cannot be initialized with a value of type "bool (const Line &, vec_dimension={double}, vec_dimension={double}, vec_dimension={double}, vec_dimension={double})"
    QuadTree<Line, vec_dimension, line_inside_box_with_time> *quad_tree =
                                  ^

(含g++

CollisionWorld.cpp:73:58: error: could not convert template argument ‘CollisionWorld::line_inside_box_with_time’ to ‘bool (&)(const Line&, double, double, double, double)’
   QuadTree<Line, vec_dimension, line_inside_box_with_time> *quad_tree =
                                                          ^

问题是模板需要一个自由函数,而不是一个成员函数。这就是为什么当你把 bar() 从 Foo 中放出来时它会起作用的原因,

像这样尝试:

template<typename C, bool (C::*func)(int arg)>
bool id(C *mthis, int arg) {
  return (mthis->*func)(arg);
}
class Foo {
 public:
  Foo() {};
  virtual ~Foo() {};
  bool bar(int arg) { return true; }
  bool bar2(int arg) {
    return id<Foo, &Foo::bar>(this, arg);
  };
};

要调用成员函数,您需要两样东西:this指针和函数。因此,它不可能像你写的那么容易。 id需要this指针!

模板定义如下所示:

template<bool (Foo::*func)(int)>

但是,您仍然无法实现同时适用于函数和成员函数的真正id函数。