std::invoke_result_t搭配std::mem_fn时static_assert断言失败的原因咨询
std::invoke_result_t搭配std::mem_fn时static_assert断言失败的原因咨询
嘿,这个问题我之前踩过一模一样的坑,咱们一步步拆解来搞明白哈~
你代码里的核心问题在于**std::mem_fn生成的函数对象,调用后返回的是成员的引用类型,而非你预期的值类型**。
咱们来具体捋清楚细节:
- 你用
std::mem_fn(&Device::Version)创建的getter函数对象,它的设计目的是保留成员的原生访问属性——当你传入Device&类型的实例去调用它时,会直接返回Version成员的左值引用,也就是std::string&,这样既支持读取成员值,也允许通过这个引用修改成员。 - 而你代码里的
using Field = std::invoke_result_t<Getter, Device&>,这里推导出来的Field实际是std::string&,但你在static_assert里把它和std::string做比较,自然就触发断言失败了。
那怎么调整才能符合你的预期呢?有两个常用方案:
- 如果你接受引用类型,直接修改断言语句为
static_assert(std::is_same_v<Field, std::string&>);,这样就能正常通过。 - 如果你确实需要值类型
std::string,可以用std::decay_t来剥离引用属性,比如:
这样处理后,using Field = std::decay_t<std::invoke_result_t<Getter, Device&>>;Field就会变成你最初预期的std::string,断言也能顺利通过。
你也可以加个小测试验证这个结论:
Device d("v1", 1, {}); auto val = getter(d); static_assert(std::is_same_v<decltype(val), std::string&>); // 这个断言会成功
这样是不是就搞清楚为啥断言失败啦?
内容来源于stack exchange
相关产品推荐
相关产品推荐

