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

如何判断函数为非void类型?我的C++ Concept验证代码为何失效?

问题分析与解决

你的Concept实现逻辑存在错误:requires表达式中直接放置编译期布尔值时,仅会检查该布尔表达式是否合法编译,而非其值的真假。

对于你的bad结构体,t.operator[](val)是合法可调用的,因此decltype(t.operator[](val))能正确推导为void,进而!std::is_same<decltype(t.operator[](val)), void>::value这个表达式本身是合法的(尽管它的值是false),所以整个requires子句会被判定为满足,最终导致Indexable<bad>被错误地认为是true。

而std::map的测试能通过,只是因为其operator[]返回非void类型,此时布尔表达式的值为true,恰好符合预期,但这只是巧合,并非你的Concept逻辑正确。


正确的实现方式

你需要同时满足两个条件:

  1. 类型T支持operator[]调用(即t[val]表达式合法)
  2. operator[]的返回值类型不是void

以下是两种可靠的实现:

方式1:使用返回类型约束

#include <type_traits>
#include <map>

template<class T>
concept Indexable = requires(T t, size_t val){
    // 约束operator[]的返回类型非void
    { t[val] } -> std::negation<std::is_void>;
};

方式2:嵌套requires条件检查

#include <type_traits>
#include <map>

template<class T>
concept Indexable = requires(T t, size_t val){
    // 先确保operator[]可调用
    t[val];
    // 再检查返回值非void
    requires !std::is_void_v<decltype(t[val])>;
};

测试验证

测试返回void的结构体

struct bad {
    void operator[](size_t) {}
};
static_assert(!Indexable<bad>, "fail"); // 现在正常通过断言

测试std::map

static_assert(Indexable<std::map<int, std::string>>, "fail"); // 正常通过断言

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:22:49