具有函数指针的模板归还还原

时间:2019-01-09 10:37:06

标签: c++ templates function-pointers

我以前使用过的代码无法从g ++-5移到g ++-6;先前可推导的模板不再可推导。一个最小的例子:

#include <math.h>

template<typename T,typename T1>
T apply(T (*func)(T1), const T1 &val)
{
  return func(val);
}

int main(void)
{
  double val1 = 0.5, val2 = apply(ceil,val1);
  return 0;
}

g ++-6似乎找不到正确的ceil版本:

foo.cpp: In function ‘int main()’:
foo.cpp:11:44: error: no matching function for call to ‘apply(<unresolved overloaded function type>, double&)’
   double val1 = 0.5, val2 = apply(ceil,val1);
                                        ^
foo.cpp:4:3: note: candidate: template<class T, class T1> T apply(T (*)(T), const T1&)
 T apply(T (*func)(T), const T1 &val)
   ^~~~~
foo.cpp:4:3: note:   template argument deduction/substitution failed:
foo.cpp:11:44: note:   couldn't deduce template parameter ‘T’
   double val1 = 0.5, val2 = apply(ceil,val1);

g ++-5没有问题,可以正常工作。在https://godbolt.org/z/oBSopG使用带有g ++ 8的Compiler Explorer,我还看到从clang-3.3(编译)到clang-3.4(不编译)的还原。

鉴于该代码仍然无法正常工作,即使在当前的g ++中,我也认为错误是由我自己造成的。我做错了什么,怎么解决?

2 个答案:

答案 0 :(得分:4)

  

我做错了什么以及如何解决?

解决此问题的方法是修复#include <cmath>而不是使用reference documentation中提到的#include <math.h>

#include <cmath> // <<< official header to use.
#include <iostream>

template<typename T,typename T1>
T apply(T (*func)(T1), const T1 &val)
{
  return func(val);
}

int main(void)
{
  double val1 = 0.5, val2 = apply(ceil,val1);

  std::cout << val1 << ' ' << val2<< std::endl;
}

答案 1 :(得分:1)

如果您正在使用(或计划使用)C ++ 17,则应该知道有一个更强大的库函数可以执行您要尝试的操作:std::invoke

有了它,您的示例可以简化为:

#include <cmath>
#include <functional>

int main(void)
{
  double val1 = 0.5, val2 = std::invoke(ceil,val1);
  return 0;
}

有趣的是,对于您手工制作的apply和库std::invoke,如果您编写std::invoke(std::ceil, val1),则代码将失败。这需要进一步调查。...