On 2023-01-25 9:43 PM, Pawel Por wrote:
> Hello,
>
> Please help me to understand why in the following example MyList::push_front(T&&) receives argument by lvalue reference while std::forward_list::push_front(_Tp&&) receives argument by rvalue reference.
That is not the case.
> Thank you in advance
>
> #include <iostream>
> #include <forward_list>
>
> template <typename T>
> void p(const T &v)
> {
> std::cout << v << std::endl;
> }
>
> struct Dog
> {
> Dog() { p(__PRETTY_FUNCTION__); }
> Dog(const Dog&) { p(__PRETTY_FUNCTION__); }
> Dog(Dog&&) { p(__PRETTY_FUNCTION__); }
>
> Dog& operator=(const Dog&) { p(__PRETTY_FUNCTION__); return *this; }
> Dog& operator=(Dog &&) { p(__PRETTY_FUNCTION__); return *this; }
> };
>
> template<typename T>
> struct MyList
> {
> void push_front(T &&v) {}
> };
>
> int main(int argc, char **argv)
> {
> MyList<Dog> ml;
> std::forward_list<Dog> fl;
> Dog dog;
>
> p("ml.push_front");
> ml.push_front(std::move(dog)); // lvalue reference
> p("fl.push_front");
> fl.push_front(std::move(dog)); // rvalue reference
>
> return 0;
> }
You don't get any output from the call of `MyList::push_front` because
it doesn't do anything.
Here's more sane code:
#include <iostream>
#include <forward_list>
#include <utility>
template <typename T>
void p(const T &v)
{
std::cout << v << std::endl;
}
struct Dog
{
Dog() { p(FUNCSIG); }
Dog(const Dog&) { p(FUNCSIG); }
Dog(Dog&&) { p(FUNCSIG); }
Dog& operator=(const Dog&) { p(FUNCSIG); return *this; }
Dog& operator=(Dog &&) { p(FUNCSIG); return *this; }
};
template<typename T>
struct MyList
{
void push_front(T &&v) { T x = std::move( v ); (void) x; }
};
int main()
{
MyList<Dog> ml;
std::forward_list<Dog> fl;
Dog dog;
p("ml.push_front");
ml.push_front(std::move(dog));
p("fl.push_front");
fl.push_front(std::move(dog));
}
Output:
[C:\root\temp]
> cl _.cpp /D FUNCSIG=__FUNCSIG__
_.cpp
[C:\root\temp]
> _
__cdecl Dog::Dog(void)
ml.push_front
__cdecl Dog::Dog(struct Dog &&)
fl.push_front
__cdecl Dog::Dog(struct Dog &&)
[C:\root\temp]
> g++ _.cpp -D FUNCSIG=__PRETTY_FUNCTION__
[C:\root\temp]
> _
__cdecl Dog::Dog(void)
ml.push_front
__cdecl Dog::Dog(struct Dog &&)
fl.push_front
__cdecl Dog::Dog(struct Dog &&)
- Alf