C++11 Perfect forwarding question

closed account (o3hC5Di1)
Hi everyone,

I'm slowly starting to understand rvalue references and their benefits.
At the moment I'm creating a templated facade class, so I thought it might be the perfect time to use perfect forwarding. Unfortunately the compiler, gcc 4.6.3, is throwing me this error:

no known conversion for argument 1 from ‘type’ to ‘type&&’


Simplified version of the code I'm using:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename EntityType, typename EntityMapper>
class facade
{
    public:
        void read(EntityType&& e)
        {
            _mapper.read(std::forward<EntityType>(e));
        }

    private:
        EntityMapper _mapper;
};

//used:
facade<person, personmapper> personfacade;
person p;
personfacade.read(p);  //this fails
personfacade.read(std::move(p)); //this works 


Could anyone please explain the difference, as to why this doesn't work, but the factory function on this page does: http://thbecker.net/articles/rvalue_references/section_08.html

To me they seem to be pretty much the same, but I must be missing something.
I'm trying to understand this, not to just copy things.

Thanks very much in advance.

All the best,
NwN

Isn't p an lvalue in your code?
personfacade.read(person());
read needs to be a template function (that is,
1
2
template<typename T>
void read(T&& e)

in order to bind to both lvalues and rvalues (in which case std::forward can be used to forward the value category elsewhere)
closed account (o3hC5Di1)
Catfish3 wrote:
Isn't p an lvalue in your code?


Yes... but I understood the link I included in my post as "if you define a templated function with Type&&, the compiler will create versions as needed for both lvalues and rvalues".

I'm obviously missing something?

All the best,
NwN
Last edited on
closed account (o3hC5Di1)
Cubbi wrote:
read needs to be a template function


Hmm, I sort of hoped it would suffice to make it a member function of a class template.
Is there any alternative?

Thanks very much for your help guys :)

All the best,
NwN
Last edited on
Just like that
1
2
3
4
5
6
    public:
        template<typename T>
        void read(T&& e)
        {
            _mapper.read(std::forward<T>(e));
        }

closed account (o3hC5Di1)
Then wouldn't I have to do following?

1
2
3
facade<person, personmapper> personfacade;
person p;
personfacade.read<person>(p); 


-N
No, that would not compile. personfacade.read(p); is the intended use case.
closed account (o3hC5Di1)
That's exactly what I was after, thank you very much!
I think I can figure out whatever questions I have from the page I referred to.

Thanks again.

All the best,
NwN
Topic archived. No new replies allowed.