You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++20中用Concepts声明泛型高阶函数的签名?

解决泛型可调用对象的返回类型约束问题

原代码中std::convertible_to<std::function<int(auto)>>的写法不合法,因为int(auto)不是有效的函数类型声明,auto不能直接用于std::function的模板参数来表示泛型参数。以下是几种可行的解决方式:

1. 自定义Concept直接约束可调用行为

最直观的方式是自定义一个Concept,直接描述返回的可调用对象需要满足的条件:可以接受任意类型的参数,且返回值为int。

#include <concepts>

// 定义Concept:可接受任意参数并返回int的可调用对象
template<typename F>
concept IntReturningGenericCallable = requires(F f, auto x) {
    { f(x) } -> std::same_as<int>;
};

// 使用自定义Concept约束Foo的返回类型
IntReturningGenericCallable auto Foo() {
    return [](auto x) {
        return 1;
    };
}

int main() {
    return Foo()(1);
}

这种方式无需依赖std::function,直接对可调用对象的行为进行约束,同时避免了std::function带来的类型擦除开销,性能更优。

2. 结合std::invocable与返回值约束

也可以利用标准库的std::invocableConcept,搭配返回值的约束来实现:

#include <concepts>

template<typename F>
concept GenericIntReturner = 
    std::invocable<F, auto> && // 可被任意参数调用
    requires(F f, auto x) {
        { f(x) } -> std::same_as<int>; // 返回值必须是int
    };

GenericIntReturner auto Foo() {
    return [](auto x) { return 1; };
}

int main() {
    return Foo()(1);
}

3. 使用尾随requires子句约束返回类型

如果不想单独定义Concept,也可以直接在函数声明中用尾随requires子句来约束返回值的行为:

#include <concepts>
#include <utility>

auto Foo() -> auto requires requires(auto x) {
    // 检查返回的可调用对象调用任意x后返回int
    { std::declval<decltype(Foo())>()(x) } -> std::same_as<int>;
} {
    return [](auto x) { return 1; };
}

int main() {
    return Foo()(1);
}

这种写法无需额外定义Concept,但可读性稍差,适合简单场景。

内容的提问来源于stack exchange,提问作者bradgonesurfing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:45:33