This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
- From: "thiago at kde dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 25 Apr 2013 00:45:00 +0000
- Subject: [Bug c++/57064] [clarification requested] Which overload with ref-qualifier should be called?
- Auto-submitted: auto-generated
- References: <bug-57064-4 at http dot gcc dot gnu dot org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57064
--- Comment #1 from Thiago Macieira <thiago at kde dot org> 2013-04-25 00:45:00 UTC ---
Here's why I'm asking:
QString has members like:
QString arg(int, [other parameters]) const;
Which are used like so:
return QString("%1 %2 %3 %4").arg(42).arg(47).arg(-42).arg(-47);
// returns "42 47 -42 -47"
Right now, each call creates a new temporary, which is required to do memory
allocation. I'd like to avoid the new temporaries by simply reusing the
existing ones:
QString arg(int, [...]) const &; // returns a new copy
QString &&arg(int, [...]) &&; // modifies this object, return *this;
When these two overloads are present, every other call will be to rvalue-ref
and the others to lvalue-ref. That is, the first call (right after the
constructor) calls arg()&&, which returns an rvalue-ref. The next call will be
to arg()&, which returns a temporary, making the third call to arg()&& again.
I can get the desired behaviour by using the overloads:
QString arg(int, [...]) const &; // returns a new copy
QString arg(int, [...]) &&; // returns a moved temporary via return
std::move(*this);
However, the side-effect of that is that we still have 4 temporaries too many,
albeit empty (moved-out) ones. You can see this by counting the number of calls
to the destructor:
$ ~/gcc4.8/bin/g++ -fverbose-asm -fno-exceptions -fPIE -std=c++11 -S -o -
-I$QTOBJDIR/include /tmp/test.cpp | grep -B1 call.*QStringD
movq %rax, %rdi # tmp82,
call _ZN7QStringD1Ev@PLT #
--
movq %rax, %rdi # tmp83,
call _ZN7QStringD1Ev@PLT #
--
movq %rax, %rdi # tmp84,
call _ZN7QStringD1Ev@PLT #
--
movq %rax, %rdi # tmp85,
call _ZN7QStringD1Ev@PLT #