[英]std::function const correctness not followed
我惊讶地发现这段代码编译:
#include <functional>
struct Callable {
void operator() () { count++; }
void operator() () const = delete;
int count = 0;
};
int main() {
const Callable counter;
// counter(); //error: use of deleted function 'void Callable::operator()() const'
std::function<void(void)> f = counter;
f();
const auto cf = f;
cf();
}
https://wandbox.org/permlink/FH3PoiYewklxmiXl
这将调用Callable
的非const调用操作符。 相比之下,如果你做const auto cf = counter; cf();
const auto cf = counter; cf();
然后它按预期错误输出。 那么,为什么const正确性似乎没有跟随std::function
?
std::function
添加了一个间接层,这个间接层不会通过const
传递给callable。
我不确定为什么会这样 - 可能是因为std::function
需要一个可调用的副本而且不需要保留副本const
(实际上这可能会破坏赋值语义) - 我也不确定你为什么这么做我需要它。
(当然,直接在一个类型的对象上调用operator()
,你恰好调用Callable
并声明为const
将需要一个const
上下文,就像对任何其他对象一样。)
最佳实践是给callable一个const
operator()
并保留它。
tl; dr:是的,但不是一个bug,并不重要
你发现这很奇怪是对的。 std::function
的调用运算符标记为const
但实际调用目标对象时不会传播const
。 提议p0045r1似乎通过使std::function
非const的调用运算符但允许以下语法来解决这个问题:
std::function<return_type(arg_type) const>
原因是为std::function
对象分配counter
会创建一个counter
的副本。
在您的情况下,使用以下构造函数初始化f
:
template< class F >
function( F f );
如上所述这里 ,这个构造“与标准::移动(F)初始化目标” -类型的新对象Callable
创建和使用拷贝构造函数初始化。
如果您想使用对counter
的引用来初始化f
,则可以使用std::ref
:
std::function<void()> f = std::ref(counter);
std::ref
返回一个std::reference_wrapper
的实例,它有operator ()
,它调用Callable
的operator () const
。 正如预期的那样,您将收到错误,因为该运算符已被删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.