I'm trying to implement decorator for functions using variadic templates. And try to minimize number of overloads since it reduce the size of a compiler error messages in case of template params deducion failure. I have implementation which works with any member of any class (works with delegate Ret (Ctx::*member)(Args...)) and one extra overload which do not take pointer to member function and just calls first version passing &Ctx::opeator(). I've tried to remove extra overload by adding default value for member pointer argument here. Here is the version which compiles:
template<
typename Decorator,
typename Ctx, typename R, typename... Args,
typename... CTorArgs
>
Decorator decorate(
CTorArgs&&...cargs,
const Ctx &obj, R (Ctx::*member)(Args...) const = &Ctx::operator()
) {
return Decorator(
std::function<R(Args...)>([&obj, member](Args... args){
return (obj.*member)(args...);
}),
std::forward(cargs)...
);
}
But it can't be called without explicit member function specification. Here is an example I'm playing with right now:
struct IntDecorator {
IntDecorator(std::function<std::string(std::string)> func):
m_func(func) {}
std::string operator() (int val) {
std::ostringstream oss;
oss << val;
return m_func(oss.str());
}
private:
std::function<std::string(std::string)> m_func;
};
struct PrefixAdder {
PrefixAdder(std::string prefix): m_prefix(prefix) {}
std::string addPrefix(std::string val) const {return m_prefix + val;}
std::string operator() (std::string val) const {return m_prefix + val;}
private:
std::string m_prefix;
};
int main(int, char**) {
PrefixAdder p("+++> ");
std::cout << decorate<IntDecorator>(p, &PrefixAdder::addPrefix)(123) << std::endl;
std::cout << decorate<IntDecorator>(p, &PrefixAdder::operator())(123) << std::endl;
std::cout << decorate<IntDecorator>(p)(123) << std::endl; // compilation error
}
compiler can't deduce type R (member function return type). The code works after adding extra overload which I try to elliminate or by specifying all template parameters which is even worse than extra overload:
template<typename Decorator, typename Ctx, typename... CTorArgs>
Decorator decorate(CTorArgs&&...cargs, const Ctx &obj) {
return decorate<Decorator>(cargs..., obj, &Ctx::operator());
}
Can I have automatic type dedution without additional version of decorate template? What is the problem to deduce types automatically here in C++11?
Aucun commentaire:
Enregistrer un commentaire