I've read about perfect forwarding, but still I've got questions)
Consider this code
template<typename Input , typename Output>
struct Processor
{
Output process(Input&& input)
{
startTimer(); // Starting timer
auto data = onProcess(std::forward<Input>(input)); // Some heavy work here
stopTimer(); // Stopping timer
logTimer(); // Logging how many ms have passed
return data;
}
protected:
Output onProcess(Input&& input) = 0; // one overload for rvalue-references
Output onProcess(const Input& input) = 0; // one overload for const lvalue-references
};
My problem is that onProcess(Input&& input)
and onProcess(const Input& input)
will always do the same. How can I have one overload for both const lvalue reference and rvalue reference, will having one const lvalue reference cost me memory and performance? Also what if I had an overload with onProcess(Input& input)
how could I solve my problem then?
UPDATE
My example was not using perfect forwarding, so I've corrected it for the right context of the question
template<typename Input , typename Output>
struct Processor
{
template<class I,
std::enable_if_t<std::is_same_v<std::decay_t<I>, Input>, int>=0>
Output process(I&& input)
{
startTimer(); // Starting timer
auto data = onProcess(std::forward<I>(input));
stopTimer(); // Stopping timer
logTimer(); // Logging how many ms have passed
return data;
}
protected:
Output onProcess(Input&& input) = 0; // one overload for rvalue-references
Output onProcess(const Input& input) = 0; // one overload for const lvalue-references
};
CodePudding user response:
Perfect forwarding is possible when you have a forwarding reference.
Example:
template<class I, std::enable_if_t<std::is_convertible_v<I, Input>, int> = 0>
Output process(I&& input)
{
startTimer(); // Starting timer
auto data = onProcess(std::forward<I>(input));
stopTimer(); // Stopping timer
logTimer(); // Logging how many ms have passed
return data;
}
As for the virtual
function onProcess
, you can't have a similar construct there since virtual
functions can't be function templates. Since both overloads are supposed to do the same thing without changing the object, only make one of those functions and take the Intput
by const&
.