【问题标题】:std::function template argument deductionstd::function 模板参数推导
【发布时间】:2020-01-14 23:13:22
【问题描述】:

我已经创建了一个我当前问题的示例。 我希望能够在不指定模板类型的情况下调用以下函数,因为编译器应该能够找出类型:

template<typename T, class Iterable>
void foreach1(std::function<void(T&)> action, Iterable& iterable) {
    std::cout << typeid(T).name() << std::endl;
    for (auto& data : iterable)
        action(data);
}

如果我这样调用函数:

std::vector<int> a = { 1, 2, 3 };
foreach1([](int& data) {
    std::cout << data << std::endl;
}, a);

我得到一个错误。我知道我可以通过以下方式用模板替换 std::function 来解决问题:

template<class Action, class Iterable>
void foreach2(Action action, Iterable& iterable) {
//std::cout << typeid(T).name() << std::endl; // no access to T
for (auto& data : iterable)
    action(data);
}

但是这样做我失去了对 T 类型的访问权限。 有没有办法保持对类型 T 的访问并能够使用模板参数推导?

【问题讨论】:

标签: c++ templates std-function


【解决方案1】:

将参数传递给类型依赖于推导的模板参数的参数时,不允许进行隐式转换。

我建议使用第二个选项:

template<class Action, class Iterable>
void foreach2(Action action, Iterable& iterable)

要确定T,首先要从action 中生成std::function

std::function(action)

然后编写一个模板来获取std::function的参数类型:

template <typename T> struct std_func_param {};
template <typename R, typename T> struct std_func_param<std::function<R(T)>> {using type = T;};
template <typename T> using std_func_param_t = typename std_func_param<T>::type;

像这样使用它:

using T = std_func_param_t<decltype(std::function(action))>;

【讨论】:

  • 将 lambda 转换为 std::function 是否有运行时成本?我在某些地方读过在大多数情况下不使用 std::function 。这是你必须使用它的一种情况吗?
  • @Dolfos 可能存在运行时成本,但在这种情况下,std::function(action) 仅在 decltype() 内部使用,这意味着它不会被评估。没有构造实际的std::function
  • 如果不进行评估,为什么会有运行时成本?
  • @Dolfos 我的意思是如果评估std::function(action) 可能会有运行时成本。既然不是,就没有额外的费用。
  • 编译器是否优化了 std::function 的构造,因为 decltype() 不算“使用”变量?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多