I need to implement some methods similar to vector::emplace
for my own data structures. In the general case, I would implement them so that they support perfect forwarding, i.e., with rvalue-references, std::forward
and that stuff.
However, what if I know that all parameters to forward are primitive types such as int
or float
. Does it make any sense to implement perfect forwarding for primitive types?
In other words, is there a difference between the following two code snippets, assuming that we only use primitive types as template parameters?
template <typename... Args>
void wrapper(Args&& ... args) {
func(std::forward<Args>(args)...);
}
and
template <typename... Args>
void wrapper(Args ... args) {
func(args...);
}
Additionally: Is there any difference if we know that the template parameters can only be classes which contain only primitive types? Or classes that contains only primitive types and other classes which themselves contain only primitive types?
No, it absolutely does not make any sense to use perfect forwarding for basic types:
There is one exception though:
There is no way to avoid taking output-parameters by reference.
Also, if you are writing a template anyway, are you absolutely sure you will never want to use it with more complex types?
YAGNI (You ain't gonna need it) is very important, but not handicapping yourself later by unneccessarily restricting your interface is too.
And always remember the old adage "Premature optimization is the root of all evil".