5

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 ?!

Nikos Athanasiou
  • 29,616
  • 15
  • 87
  • 153
uchar
  • 2,552
  • 4
  • 29
  • 50

3 Answers3

7

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.);
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
6

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";
    }
};
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

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);
hivert
  • 10,579
  • 3
  • 31
  • 56
  • I think you mean "how function template arguments are deduced". – Kerrek SB Mar 04 '14 at 09:09
  • Yes ! I realized that I don't fully understand what's going on here. I asked a followup question: http://stackoverflow.com/questions/22167235/understanding-template-argument-deduction-with-rvalue-lvalue – hivert Mar 04 '14 at 09:11