如何针对特定概念(需求)重载使用 lambda 语法定义的函数?

问题描述 投票:0回答:1

我需要针对特定概念(要求)重载 lambda。它在模板语法中工作得很好,但当然“lambda 不是函数”并且不能重载。

不幸的是,上述重载 lambda 函数中提供的解决方案没有帮助,因为:

  1. 我的问题是关于概念/要求,而不是关于类型(这里的关键区别)。
  2. 总的来说,我有很多不同的概念,并且使用
    if constexpr std::is_same_v
    进行黑客攻击变得非常脆弱;添加了一个新概念,我将不得不查找并更新所有客户端代码,这是不可能的。

问题是,如果我继续使用 lambda 函数语法,我该怎么做才能对不同的概念(要求)使用相同的名称,如下所示?

#include <ranges>
#include <vector>

template <std::ranges::input_range Rng>
void fn_template(Rng& data) {
};

template <std::ranges::random_access_range Rng>
void fn_template(Rng& data) {
};

constexpr auto lambda = []<std::ranges::input_range Rng>(Rng & data) {
};

// Redefinition error, of course
constexpr auto lambda = []<std::ranges::random_access_range Rng>(Rng & data) {
};

int main()
{
    std::vector<float> v = { 0.0f, 1.0f, 0.0f, 2.0f };

    auto no_zeros = v | std::views::filter([](const auto& lhs) { return lhs != 0.0f; });

    // Works just fine
    fn_template(v);
    fn_template(no_zeros);

    // Can't achieve
    lambda(v);
    lambda(no_zeros);
}

演示

c++ templates lambda range std
1个回答
0
投票

您可以使用重载技巧,它将多个 lambda 组合成一个重载集(演示)。

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

constexpr auto lambda = overloaded(
    []<std::ranges::input_range Rng>(Rng & data) {
    },
    []<std::ranges::random_access_range Rng>(Rng & data) {
    }
);
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.