【问题标题】:Why is std::invocable concept blocking this code from compiling为什么 std::invocable 概念会阻止此代码编译
【发布时间】:2020-06-08 14:59:12
【问题描述】:

我不明白为什么在以下代码中 lambda 和函数都没有被识别为符合 std::invocable 的类型:

#include <concepts>
#include <iostream>

void f( std::invocable auto callback)
{
    callback(47);
}

void function_callback(int i)
{
    std::cout << i << std::endl;
}

auto lambda_callback = [](int i )
{
    std::cout << i << std::endl;
};

int main(int) 
{
    f(&function_callback);
    f(lambda_callback);
}

我正在使用启用了-std=c++2a 标志的 GCC 中继。

【问题讨论】:

  • 如果您遇到构建错误,请始终将它们完整完整地复制粘贴到问题本身中。并在出现错误的行上添加 cmets。

标签: c++ c++20 c++-concepts invocable


【解决方案1】:

如果你看invocable的定义(或standard):

template< class F, class... Args >
concept invocable =
  requires(F&& f, Args&&... args) {
    std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
      /* not required to be equality preserving */
  };

这是什么意思:

void f( std::invocable auto callback)

如果我们把它写成长格式可能会更清楚:

template <typename F>
    requires std::invocable<F>
void f(F callback);

F 是不是可以用 no arguments 调用 - 它是一个空函数(Args... 在这里是一个空包)。您的函数和 lambda 都不是空函数 - 它们都是一元函数,因此约束正确地拒绝了这些函数。

你可能想要的是:

void f( std::invocable<int> auto callback)

检查callback 是否可以使用int 类型的单个参数调用。

【讨论】:

  • 我不是 100% 确定我已经理解为什么 Args... 被认为是 无参数 而不是自动推断为 int 的原因,但您提出的修复工作有效.
  • @nyarlathotep108 概念从不推导出来。指定概念。
  • 有没有办法使用概念真正说出“任何”可调用类型,而无需回滚到模板语法?
  • @nyarlathotep108 你会用这些信息做什么?您有一个模板,它受限于可调用的类型以某种方式 - 但您不知道如何?一般意义上,连回答都不可能。
  • @nyarlathotep108:记住:约束应该表达你打算如何使用一个东西。你不会用“任何”参数来调用它;您将使用 some 参数调用它。所以你的约束应该表达你对函数使用的意图。
猜你喜欢
  • 2021-02-20
  • 1970-01-01
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
相关资源
最近更新 更多