为何带引用限定符调用运算符的仿函数不满足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
相关产品推荐
相关产品推荐

