c++ - Makes it any sense to declare RValue methods (e.g. void operation() &&;) virtual C++1x -
this maybe exotic: (i´m working on update new c++ standard ) there case makes sense declare rvalue method in class e.g. void operation() &&; virtual? can not imagine, because operation applicable temporary objects, e.g. base().operation() or derived().operation() or createobject().operation(). expression createobject() must return object , not reference nor pointer, because must both refere lvalue object. , because of type slicing, base::operation() called. if have object of derived(), derived::operation() called, nevertheless virtual in base or not. so, there case understood me, i´ve overseen? inspiration!
oh yes, forgot, there casts rvalue: move , forward! that!
my findings are: 1. call rvalue reference qualified operation (rqop() &&), have use std::forward<..> exception: derived().rqop(); 2. makes sense declare rvalue reference qualified operations virtual
because of following: given classes base , derived overloaded reference qualified operation rqop() , non reference qualified 1 called op():
class base{ public: virtual ~base() = default; virtual void rqop() &&; virtual void rqop() &; virtual void op(); }; class derived : public base{ public: //virtual void rqop() &&; //override; virtual void rqop() & override; virtual void op() override; }; and overloaded function:
void calloperationf(base& b){ cout << "calloperationf(base& b)" << endl; cout << "b.rqop();" << endl; b.rqop(); } void calloperationf(base&& b){ cout << "calloperationf(base&& b)" << endl; cout << "b.rqop();" << endl; b.rqop(); cout << "std::forward<base&&>(b).rqop();" << endl; std::forward<base&&>(b).rqop(); cout << "std::forward<base&&>(b).op();" << endl; std::forward<base&&>(b).op(); } and calls overload:
cout << "== derived d;" << endl; derived d; cout << endl; cout << "== calloperationf(d);" << endl; calloperationf(d); cout << endl; cout << "== calloperationf(derived());" << endl; calloperationf(derived()); results in output:
== derived d; == calloperationf(d); calloperationf(base& b) b.rqop(); derived::rqop() & == calloperationf(derived()); calloperationf(base&& b) b.rqop(); derived::rqop() & ===> 1 std::forward<base&&>(b).rqop(); derived::rqop() && ===> 2 std::forward<base&&>(b).op(); derived::op() as can see, call rvalue reference qualified operation (rqop() &&), need use forward<..> @ ===> 1 not rvalue qualified called! because b lvalue expression. @ ===> 2 std::forward<..> correct method called , also
not reference qualified operation (op()) correct called std::forward<...>. if change interface , overload op() reference qualified, still call correct method, rvalue reference qulified one.
with templatized function, this:
template<class t> void calloperationt(t&& t){ cout << "calloperationt(t&& t)" << endl; cout << "t.rqop()" << endl; t.rqop(); cout << "std::forward<t>(t).rqop();" << endl; std::forward<t>(t).rqop(); cout << "std::forward<t>(t).op();" << endl; std::forward<t>(t).op(); } and calls function, derived d above:
cout << endl; cout << "== calloperationt(d);" << endl; calloperationt(d); cout << endl; cout << "== base& bref = d;" << endl; base& bref = d; cout << "== calloperationt(move(bref));" << endl; calloperationt(move(bref)); cout << endl; cout << "== calloperationt(derived());" << endl; calloperationt(derived()); results in output:
== calloperationt(d); calloperationt(t&& t) t.rqop() derived::rqop() & std::forward<t>(t).rqop(); derived::rqop() & std::forward<t>(t).op(); derived::op() == base& bref = d; == calloperationt(move(bref)); calloperationt(t&& t) t.rqop() derived::rqop() & std::forward<t>(t).rqop(); derived::rqop() && ===> 3 std::forward<t>(t).op(); derived::op() == calloperationt(derived()); calloperationt(t&& t) t.rqop() derived::rqop() & std::forward<t>(t).rqop(); derived::rqop() && std::forward<t>(t).op(); derived::op() with same finding: call rvalue reference qualified operation (rqop() &&), need use forward<..> @ ===> 3 base::rqop() && called, if rqop not virtual.
thank you!
i can not imagine, because operation applicable temporary objects
not necessarily. rvalue ref-qualified function requires object bound rvalue reference. is, can have function returns rvalue reference base dynamic type derived:
struct base { virtual void f() && { std::cout << "base\n"; }; virtual ~base() = default; }; struct derived : base { void f() && override { std::cout << "derived\n"; } } child; base&& get() { return std::move(child); } int main() { get().f(); // derived }
Comments
Post a Comment