自动构造函数不使用<functional>对象

Auto-constructor not working with <functional> objects

本文关键字:lt gt 对象 functional 构造函数      更新时间:2023-10-16

考虑以下代码:

class _c {
    public:
    _c(int);
    _c(function<void(void)>);
};

一个类,具有分别为intfunction<void(void)>定义的两个构造函数。

这意味着我现在可以实例化像这样的类的对象:

_c a = _c(0);
_c b = _c([]() {});

现在,我声明一个以_c对象为参数的函数:

void _f(_c __c) {};

现在我可以用_c对象调用这个函数,如下所示:

_f(_c(0));
_f(_c([]() {}));

在这里之前,一切看起来都很好。现在,如果我尝试在不显式调用_c构造函数的情况下调用我的_f函数,我会看到:

_f(0) // works because C++ knows to construct a _c with an 0 by using _c(int)

但是,

_f([]() {}) // fails with 'no matching function for call to _f'

我不明白为什么会发生这种情况,有人能解释一下为什么在使用<functional>类型时它不起作用吗?

此外,我正在使用:Apple LLVM 6.0版(clang-600.0.57)(基于LLVM 3.5svn)

进行编译

调用f(0)时,参数的类型为int,可以转换为_c。这是常见的一步转换。

但是,当调用_f([]() {})时,参数是lambda类型(由编译器生成),而不是std::function<void(void)>类型。因此,在这种情况下,它需要两次转换—一个是从lambda类型到std::function<void(void)>,然后到_c(使用转换构造函数)。

两步转换是语言所不允许的,这就是代码不起作用的原因。

解决方案是添加一个模板化构造函数作为:

template<typename Functor, typename =decltype(std::declval<Functor&>()())>
_c(Functor && func);

那么您的代码应该可以工作了。