问题
Consider the following code:
class _c {
public:
_c(int);
_c(function<void(void)>);
};
A class with two constructors defined for an int and a function<void(void)> respectively.
Which means that I can now instantiante objects of those class like this:
_c a = _c(0);
_c b = _c([]() {});
Now, I declare a function that takes a _c object as an argument:
void _f(_c __c) {};
And now I can call this function with my _c objects like this:
_f(_c(0));
_f(_c([]() {}));
Until here, everything looks good. Now, if I try to call my _f function without explicity invoking the _c constructor I see that:
_f(0) // works because C++ knows to construct a _c with an 0 by using _c(int)
but,
_f([]() {}) // fails with 'no matching function for call to _f'
I don't understand why is this happening, could someone please explain why doesn't it work when using a <functional> type?
Also, I'm compiling with: Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
回答1:
When you call f(0), the argument is of type int which can convert into _c. It is usual one-step conversion.
However, when you call _f([]() {}), the argument is lambda-type (generated by the compiler), not of the type std::function<void(void)>. So in this case, it needs two conversions — one from lambda-type to std::function<void(void)>, then to _c (using the conversion-constructor).
The two-steps conversion is not allowed by the language,which is why your code doesn't work.
The solution is to add a templated constructor as:
template<typename Functor, typename =decltype(std::declval<Functor&>()())>
_c(Functor && func);
Then your code should work.
来源:https://stackoverflow.com/questions/31147081/auto-constructor-not-working-with-functional-objects