c++ class template can be instantiated but a function template instantiation with the same template parameters fails -
i have wrapper class binded function calls (a helper class fight legacy code issues):
template <class result, class... args> class functionwrapper { std::function<result()> func_; public: functionwrapper(std::function<result(args...)> f, args&&... args) : func_(std::bind(f, std::forward<args>(args)...)) { } //...some methods using func_ };
i can write following code, compiles , works fine:
double f(int i, double d) { return i*d; } //... functionwrapper<double, int, double> w(f, 2, 4.5); //calling methods of w ...
now want save me typing when defining wrapper instance, i've introduced make_wrapper
function:
template <class result, class... args> functionwrapper<result, args...> make_wrapper(std::function<result(args...)> f, args&&... args) { return functionwrapper<result, args...>(f, std::forward<args>(args)...); }
although template parameter list function identical 1 of the wrapper class can not compiled (adding template parameters "help" compiler doesn't either):
auto w1=make_wrapper(f, 2, 4.5); //error: no matching function call 'make_wrapper', candidate template ignored: not match 'function<type-parameter-0-0 (type-parameter-0-1...)>' against 'double (*)(int, double)' auto w2=make_wrapper<double, int, double>(f, 2, 4.5); //error: no matching function call 'make_wrapper', candidate template ignored: not match 'function<double (int, double, type-parameter-0-1...)>' against 'double (*)(int, double)'
the compiler llvm 6.1 (the current xcode one). so, going on here? possible fix make
function?
the problem first argument make_wrapper()
doesn't have type claim has. although function pointer convertible corresponding std::function<...>
compiler won't use std::function<...> deduce template arguments. if you'd make nested type have
args...be deduce other argument, the
result` type cannot deduced conversion.
if want bind function pointers, should work expect @ function pointer argument:
template <class result, class... args> functionwrapper<result, args...> make_wrapper(result (*f)(args...), args&&... args) { return functionwrapper<result, args...>(f, std::forward<args>(args)...); }
when arguments of function pointer , arguments passed disagree, may necessary have separate template argument lists function arguments , parameters bound:
template <class result, class... fargs, class... args> functionwrapper<result, fargs...> make_wrapper(result (*f)(fargs...), args&&... args) { return functionwrapper<result, fargs...>(f, std::forward<args>(args)...); }
i go alternative doesn't care actual type of function object argument , deduces whatever function type produced:
template <class fun, class... args> auto make_wrapper(fun fun, args&&... args) -> functionwrapper<decltype(fun(std::forward<args>(args)...)), args...> { return functionwrapper<decltype(fun(std::forward<args>(args)...)), args...>(f, std::forward<args>(args)...); }
Comments
Post a Comment