Den lör 27 okt. 2018 kl 22:23 skrev Thiago Macieira <thiago.macie...@intel.com>: > > On Saturday, 27 October 2018 08:33:30 PDT Sérgio Martins wrote: > > Should we instead just encourage people to make returnsQtContainer() > > return a const container ? > > We should not, since the prevents move-construction from happening. You'll pay > the cost of two reference counts (one up and one down).
Though hmm, even if we'd lose move-construction, for the copy we'd get instead, wouldn't copy elision kick in and elide it? So we wouldn't have to pay for the ref count up/down? I simplified my example a little, so to recap: $ cat copytest.cpp #include <iostream> #include <vector> struct Foo { Foo() { std::cout << this << " constructed" << std::endl; } Foo(const Foo &) { std::cout << this << " copy constructed" << std::endl; } Foo(Foo &&) { std::cout << this << " move constructed" << std::endl; } ~Foo() { std::cout << this << " destructed" << std::endl; } std::vector<int>::iterator begin() { std::cout << this << " begin" << std::endl; return v.begin(); }; std::vector<int>::const_iterator begin() const { std::cout << this << " begin const" << std::endl; return v.begin(); }; std::vector<int>::iterator end() { std::cout << this << " end" << std::endl; return v.end(); }; std::vector<int>::const_iterator end() const { std::cout << this << " end const" << std::endl; return v.end(); }; std::vector<int> v{1, 2, 3}; }; Foo f() { Foo foo; return foo; } const Foo constF() { Foo foo; return foo; } template <typename T> const T moveToConst(T &&t) { return std::move(t); } int main(void) { std::cout << "without moveToConst:" << std::endl; for (auto v : f()) { } std::cout << std::endl; std::cout << "with moveToConst:" << std::endl; for (auto v : moveToConst(f())) { } std::cout << std::endl; std::cout << "with returning const:" << std::endl; for (auto v : constF()) { } std::cout << std::endl; std::cout << "with recommended way:" << std::endl; const auto stuff = f(); for (auto v : stuff) { } return 0; } Result: $ g++ -std=c++17 -O0 -o copytest copytest.cpp $ ./copytest without moveToConst: 0x7ffcc6ac76b0 constructed 0x7ffcc6ac76b0 begin 0x7ffcc6ac76b0 end 0x7ffcc6ac76b0 destructed with moveToConst: 0x7ffcc6ac7710 constructed 0x7ffcc6ac76d0 move constructed 0x7ffcc6ac7710 destructed 0x7ffcc6ac76d0 begin const 0x7ffcc6ac76d0 end const 0x7ffcc6ac76d0 destructed with returning const: 0x7ffcc6ac76f0 constructed 0x7ffcc6ac76f0 begin const 0x7ffcc6ac76f0 end const 0x7ffcc6ac76f0 destructed with recommended way: 0x7ffcc6ac7710 constructed 0x7ffcc6ac7710 begin const 0x7ffcc6ac7710 end const 0x7ffcc6ac7710 destructed So it looks like the copy has been elided also in the "with returning const" case. Anyone know if this is guaranteed in C++17, or just permitted? If I compile with -fno-elide-constructors to disable elision: $ g++ -std=c++17 -fno-elide-constructors -O0 -o copytest copytest.cpp $ ./copytest without moveToConst: 0x7ffe7c107070 constructed 0x7ffe7c1070f0 move constructed 0x7ffe7c107070 destructed 0x7ffe7c1070f0 begin 0x7ffe7c1070f0 end 0x7ffe7c1070f0 destructed with moveToConst: 0x7ffe7c107070 constructed 0x7ffe7c107150 move constructed 0x7ffe7c107070 destructed 0x7ffe7c107110 move constructed 0x7ffe7c107150 destructed 0x7ffe7c107110 begin const 0x7ffe7c107110 end const 0x7ffe7c107110 destructed with returning const: 0x7ffe7c107070 constructed 0x7ffe7c107130 move constructed 0x7ffe7c107070 destructed 0x7ffe7c107130 begin const 0x7ffe7c107130 end const 0x7ffe7c107130 destructed with recommended way: 0x7ffe7c107070 constructed 0x7ffe7c107150 move constructed 0x7ffe7c107070 destructed 0x7ffe7c107150 begin const 0x7ffe7c107150 end const 0x7ffe7c107150 destructed $ What I find surprising here is that with the -fno-elide-constructors flag, in the "with returning const", the move constructor *is* called. Didn't we just say it wouldn't, because the const rvalue wouldn't bind to the non-const rvalue reference? I'm a little confused :p Elvis > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > > > _______________________________________________ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development