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

为何带引用限定符调用运算符的仿函数不满足std::invocable要求?

为何C++标准不将带有引用限定符调用运算符的仿函数判定为可调用?

以下为复现该问题的测试代码:

#include <concepts>
    
struct f   { auto operator()()        {} };
struct fr  { auto operator()() &      {} };
struct fcr { auto operator()() const& {} };
struct frr { auto operator()() &&     {} };

static_assert(std::copy_constructible<f>);   // ok
static_assert(std::copy_constructible<fr>);  // ok
static_assert(std::copy_constructible<fcr>); // ok
static_assert(std::copy_constructible<frr>); // ok

static_assert(std::invocable<f>);   // ok
static_assert(std::invocable<fr>);  // 编译失败
static_assert(std::invocable<fcr>); // ok
static_assert(std::invocable<frr>); // ok

有观点认为该现象和std::declval返回临时对象的实现机制有关,但实现细节本不应该对外暴露干扰用户判断,从语义层面来说,上述测试用例里的各类仿函数可调用性不应该出现判定差异。


std::invocable与std::function的判定标准矛盾

二者对可调用(callable)对象的判定规则存在明显冲突,复现代码如下:

#include <functional>

using tf   = decltype(std::function{f{}});   // ok
using tfr  = decltype(std::function{fr{}});  // ok
using tfcr = decltype(std::function{fcr{}}); // ok
using tfrr = decltype(std::function{frr{}}); // 编译失败

MSVC编译器的异常编译表现

更反常的是,MSVC v19.32版本可以正常编译通过以下代码,该表现是否属于MSVC的编译器bug?

template<std::invocable F>
auto g() -> void {}

using tg   = decltype(g<f>);   // ok
using tgr  = decltype(g<fr>);  // ok
using tgcr = decltype(g<fcr>); // ok
using tgrr = decltype(g<frr>); // ok

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:51:05