【问题标题】:templated function pointer as template parameter模板化函数指针作为模板参数
【发布时间】:2017-02-28 15:55:04
【问题描述】:

我在处理模板时偶然发现了一个困扰我的小问题。这是一个例子:

template<class _returnType, _returnType (*_function)()>
_returnType aliasGetter() { return _function(); }
int getCoolNumber() { return 42; }
int main()
{ 
    std::cout << aliasGetter<int, &getCoolNumber>(); //42
}

此代码有效(http://cpp.sh/,如果您想尝试它),但是由于我将函数指针作为模板参数,我不应该需要 _returnType,它就在函数签名中,问题是,无论如何我努力尝试,我找不到摆脱这个额外模板参数的方法。

我怎样才能让aliasGetter 只接受一个模板参数(一个指向别名的getter 的指针)? 如果这不可能,为什么不呢?

【问题讨论】:

  • 使用单个模板参数并依赖模板参数推导怎么样?
  • @WhiZTiM 这需要在运行时将函数指针传递给调用。
  • 您需要它,因为您的第二个模板参数依赖于它。你可以用functionalcpp.wordpress.com/2013/08/05/function-traits 建立一些东西,但我怀疑你会保存模板参数。

标签: c++ templates c++14


【解决方案1】:

在 C++17 中,这将成为可能,感谢template auto

template <auto F> std::invoke_result_t<F> aliasGetter() { return F(); }

在 C++17 之前,这是不可能的。您需要指定非类型模板参数的类型 - 没有办法解决这个问题。您也不能为此创建工厂,因为您不能通过函数模板传递函数指针并使其最终成为非类型模板参数。


C++14 中最短的解决方法是,唉,使用宏:

template <class T, T F> std::result_of_t<T()> aliasGetter() { return F(); }
#define TEMP_ALIAS(x) decltype(x), x

std::cout << aliasGetter<TEMP_ALIAS(&getCoolNumber)>();

无需手动输入两次即可获得函数指针的类型。

【讨论】:

  • 由于您描述的新语法,我知道 C+17 是可能的,但是,我认为也许,它可以在没有这个魔术的情况下完成(这就是我标记 C++14 的原因) .不过,这仍然是一个很好且明确的答案
  • std::result_of 在 C++17 上是 deprecated,请改用 std::invoke_result
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 2021-12-10
  • 2019-04-13
  • 2015-06-29
相关资源
最近更新 更多