【问题标题】:Points to member variables and templating指向成员变量和模板
【发布时间】:2014-05-16 19:01:01
【问题描述】:

我目前正在使用模板函数来评估数学函数的导数,就像这样

template <class func_type>
arma::mat matrixDerivative
   (func_type func, const double x, double h, double b=1.4) {
      // <implementation details>
}

模板参数允许我使用函数指针或仿函数来计算右侧。

有没有一种简单的方法可以扩展它来评估作为类方法的函数的衍生物?我无法理解如何使用指向成员函数的函数指针,也无法弄清楚将仿函数作为类属性仍然可以访问其父属性和方法的细节。

我的问题通常不清楚,因此请在回答之前随时在 cmets 中寻求澄清。

【问题讨论】:

  • 你的编译器支持 C++11 吗?
  • 通常你将一个指向对象的指针包装在一个“函子”类中,并通过该类的operator() 中的指针成员调用成员函数。这可以通过 C++11 中的 std::bindstd::mem_fn 或 C++03 中的 std::mem_fun 来简化。
  • 是的,它支持 C++11。能举个简单的例子吗?

标签: c++ templates c++11 functor member-function-pointers


【解决方案1】:

在 C++11 中只需使用 lambda:

[&]( double x )->double {
  return ptr->method(x);
}

它生成一个可以用double 调用的函数对象。上面的构造假定 lambda 将在当前作用域结束之前被使用和丢弃(否则[&amp;] 是不安全的)。

请注意,-&gt;double 可以省略 C++11 中的单行和 void 返回 lambda,如果您对它推导的返回类型没问题,即使在 C++1y 中的多行 lambda 上也可以省略(基于函数中的第一个 return 语句)。

在C++03中,可以使用std::mem_fun,也可以创建自定义函数对象。

在 C++1y 中:

[&](auto&&... x) {
  return ptr->method(std::forward<decltype(x)>(x)...);/
}

创建一个完美转发函子包装器。即使在 C++1y 中,在严肃的工业库代码之外,我也很少做这种事情。我们得到的不那么冗长:

[&](auto&&... x) {
  return ptr->method(x...);
}

这让我们可以不完美地转发,并将重载的选择推迟到 lambda 的使用点,而不是编写 lambda 的点,这可能很好。 (如果任何方法使用右值或按值调用,回到完美转发变得很诱人)

在 C++11 中,std::mem_fn 要求不重载相关方法,或者手动解决重载问题(使用神秘的强制转换)。 std::bind 然后用完美转发函数对象包装它。此过程的主要优点是可以确定构造的类型,而实现已定义,因此您可以拥有一个返回相关类型的函数。然而,这是一个非常深奥的优势:我会选择 lambda。

Lambdas 虽然很奇怪,但在 C++ 中越来越常见,并且根据我的经验,它们比链式 bind mem_fun 表达式更容易理解,因为它们看起来更像“正常”代码(在你结束之后“魔法”)。

【讨论】:

  • 这可以在尚未实例化对象的库中完成吗?
  • @JoeyDumont 我不明白你的问题。请澄清。如果您要问的是,您不能在不存在的类的实例上调用方法吗? (那应该怎么做?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 2015-09-15
  • 2017-01-16
  • 1970-01-01
相关资源
最近更新 更多