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

时间:2015-06-30 19:42:22

标签: c++ constructor

请考虑以下代码:

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([]() {}));

直到这里,一切看起来都不错。现在,如果我试图在没有明确调用_f构造函数的情况下调用我的_c函数,我会看到:

_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)

1 个答案:

答案 0 :(得分:3)

当您致电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);

然后你的代码应该可以工作。