Let's say we have a class template like this:
template<typename F>
class A
{
public:
template<typename... Args>
A(F f, Args... args)
{ /* Do something... */ }
};
And now I want to use it in some way like this one:
A<int(int)> a(::close, 1);
Now the question: is there any way to omit the <int(int)>
because a compiler can know this information for the ::close
? There is no need to save the "design" of the template.
As for concrete task, I need to design a template of a class. Objects of this class could take a function and parameters for this function at construction time and call this function later.
No, you (currently) cannot. The standard way of doing this is by creating "make_like" function (such as make_pair
, make_optional
...):
template<typename F, typename... Args>
A<std::decay_t<F>> make_A (F &&f, Args&&... args) {
return {std::forward<F>(f), std::forward<Args>(args)...};
}
C++17 will introduce template argument deduction for class which will allow you to do exactly what you want (see also Barry's answer below).
Thanks to the adoption of template parameter deduction for constructors, in C++17, you'll be able to just write:
A a(::close, 1);
Before that, you'll just need to write a factory to do the deduction for you:
template <class F, class... Args>
A<std::decay_t<F>> make_a(F&& f, Args&&... args) {
return {std::forward<F>(f), std::forward<Args>(args)...};
}
auto a = make_a(::close, 1);
This is a little verbose, but at least you don't need to worry about efficiency - there will be no copies made here thanks to RVO.
You cannot omit the arguments of a template class, unless they are defaulted. What you can do is have a maker function which deduces the argument and forwards this argument to the template class, returning an object of the appropriate instantiation.
template<typename F, typename... Args>
A<F> make_A(F f, Args&&... args) {
return A<F>(f, std::forward<Args>(args)...);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With