I have a problem in my code
Here is simplified version of it :
#include <iostream>
class A
{
public :
template <class T>
void func(T&&)//accept rvalue
{
std::cout<<"in rvalue\n";
}
template <class T>
void func(const T&)//accept lvalue
{
std::cout<<"in lvalue\n";
}
};
int main()
{
A a;
double n=3;
a.func(n);
a.func(5);
}
I expect the output to be :
in lvalue
in rvalue
but it is
in rvalue
in rvalue
why ?!
template <class T> void func(T&&)
is universal reference forwarding reference.
To test what you want, try: (Live example)
template <typename T>
class A
{
public:
void func(T&&)//accept rvalue
{
std::cout<<"in rvalue\n";
}
void func(T&)//accept lvalue
{
std::cout<<"in lvalue\n";
}
};
int main()
{
A<double> a;
double n = 3;
a.func(n);
a.func(5.);
}
To build on Jarod42's fine answer, if you want to keep the design of having a primary function template, you can decide based on the deduced type of the universal reference parameter:
#include <iostream>
#include <type_traits>
struct A
{
template <typename T> // T is either U or U &
void func(T && x)
{
func_impl<T>(std::forward<T>(x));
}
template <typename U>
void func_impl(typename std::remove_reference<U>::type & u)
{
std::cout << "lvalue\n";
}
template <typename U>
void func_impl(typename std::remove_reference<U>::type && u)
{
std::cout << "rvalue\n";
}
};
I think the surprise comes from the way the template argument are deduced. You'll get what you expect if you write:
a.func<double>(n);
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