I want to overload two functions based on whether the argument is a temporary object, so I write code like this:
#include <iostream>
void f(int &&)
{
std::cout << "&&" << std::endl;
}
void f(const int&)
{
std::cout << "const &" << std::endl;
}
int main()
{
int i;
f(i);
f(i + 1);
}
And it corrently output:
const &
&&
However, when I change the code to use template like this:
#include <iostream>
template <typename T>
void f(T &&)
{
std::cout << "&&" << std::endl;
}
template <typename T>
void f(const T&)
{
std::cout << "const &" << std::endl;
}
int main()
{
int i;
f(i);
f(i + 1);
}
The output becomes:
&&
&&
What's the problem? How can I optimize for moveable temporary object when using template?
edit:
Actually, this is a test code when I read C++ Primer. It says:
template <typename T> void f(T&&); // binds to nonconst rvalues
template <typename T> void f(const T&); // lvalues and const rvalues
After my experiment, it seems the book makes a mistake here.
template <typename T>
void f(T &&)
{
std::cout << "&&" << std::endl;
}
Uses universal forwarding reference and allows any types with reference collapsing.
You have to use T
with a no deducing context as wrapping your code into a struct:
template <typename T>
struct helper
{
void f(T &&)
{
std::cout << "&&" << std::endl;
}
void f(const T&)
{
std::cout << "const &" << std::endl;
}
};
template <typename T>
void f(T &&t)
{
helper<typename std::decay<T>::type>().f(std::forward<T>(t));
}
Live example
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