【问题标题】:Generic lambda argument for std::pairstd::pair 的通用 lambda 参数
【发布时间】:2016-06-10 13:04:30
【问题描述】:

我试图看看这在 C++14 通用 lambda 中是否可行,但我找不到正确的方式来表达它(或者可能是不可能的)。简化的例子是:

auto confirmOperation = [](auto pr){
  assert(pr.second);
};

这个想法是,如果你向它传递一个std::pair,其中second 是一个bool(例如从emplace 函数返回的内容),它可以查看这个布尔值。

如果这是一个模板参数,我可以将 pair 显式显示为通用类型,但我认为这不可能使用 lambda?因此,我将整个参数标记为泛型,因此编译器似乎无法推断出我正在将映射的 emplace() 返回传递给它。

有什么办法吗?

【问题讨论】:

  • 能否请您显示周围的代码(即包含地图位置)?
  • 你在这里要求什么? auto可以表示pair的泛型类型。你想通过返回中的类型来改变函数的行为吗?
  • 所以,很多人点赞并收藏了这个。如果您能阅读以上内容并解释您认为 OP 在说什么,您能帮我翻译一下吗?
  • 您发布的代码没有问题。它在哪些方面无法满足您的需求?

标签: c++ c++14


【解决方案1】:

您可以使用 enable_if 约束 lambda:

auto confirmOperation = [](auto pr) ->
    std::enable_if_t<std::is_same<decltype(pr.second), bool>::value> {
  assert(pr.second);
};

Example.

【讨论】:

  • 哇,真功夫。
  • @ecatmur 是的,这就是为什么我也使用decltype(pr.second) ;)
  • 虽然简洁,但这如何回答 OP 的“问题”?简而言之,您为什么认为这是 OP 所要求的?
  • @Yakk 如果您对 OP 想要什么有一些澄清,请告知我们(my comment 似乎没有完成工作。)否则这是一个很好的答案。它也被给予了 OP 的seal of kung fu,所以这很重要。
【解决方案2】:

你可以定义一个实现细节模板函数:

template<typename T>
void lambda_impl(std::pair<T, bool> const &p) {
  assert(p.second);
}

然后在你的 lambda 中调用它:

auto f = [](auto p) { lambda_impl(p); };

随着 Concepts-Lite 的出现,未来可能会提供以下方案。目前它仅适用于 GCC:

auto f = [](std::pair<auto, auto> const &p) { assert(p.second); };

甚至更好:

auto f = [](std::pair<auto, bool> const &p) { assert(p.second); };

由于auto 参数不是 C++14 的一部分,因此 P.S Clang 不编译它是正确的。

【讨论】:

  • 这不会在启用 c++14 的 clang 上编译
  • 非常漂亮,但我的带有 -std=c++14 的 Clang 无法编译它。它说:'auto' not allowed in template argument 并强调了pair 中的第一个auto 你在那里
  • 这很可悲,因为它在coliru.stacked-crooked.com/a/288f843d3219dc07 上编译。这是标准还是 GCC 扩展?
  • 在 MSVS2015 上也失败(我知道这不是检查合规性的好工具)。
  • 来自 cppreference:“如果 auto 用作参数的一种类型,则 lambda 是通用 lambda。”。由于auto 不是参数的类型,所以它不能是通用的 lambda。不过,我认为这是一个很好的功能。
【解决方案3】:

看来你可以在这里使用is_samestatic_assert

[](auto pr){
    static_assert(is_same_v<decltype(pr.second), bool>);
    assert(pr.second);
};

或者如果 C++17 不是一个选项,则需要向static_assert 发送消息,您将无法使用is_same_v

[](auto pr){
    static_assert(is_same<decltype(pr.second), bool>::value, "ouch");
    assert(pr.second);
}

Live Example

【讨论】:

  • static_assert 不是只有 C++17 没有消息吗?如果pr.second 不是一个有效的表达式会怎样?
  • @KABoissonneault 你是对的。我只使用 C++14 编写了一个实时示例。如果pr.second 无效,则static_assert 将触发。我们一开始就想要什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-09
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多