Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <utility>
- /*
- Tested with:
- i686:
- clang++ -O4 --std=c++14 msm.cc
- clang++ -O0 --std=c++14 msm.cc
- x86_64:
- g++ -O3 --std=c++14 msm.cc
- g++ -O0 --std=c++14 msm.cc
- g++ -O3 -fno-elide-constructors --std=c++14 msm.cc
- x86_64:
- cl /Ox /EHsc msm.cc
- cl /EHsc msm.cc
- Move constructors are agressively optimized by CLang++ and G++,
- until told -fno-elide-constructors http://stackoverflow.com/a/8758168/539470,
- and less agressively with Visual C++. See (1-3) below.
- */
- std::string shorten(std::string s)
- {
- return s.size() <= 16 ? s : std::string(s.begin(), s.begin() + 16) + "...";
- }
- class T
- {
- private:
- const void *tmp;
- public:
- std::string s;
- explicit T(const std::string& s0):
- tmp(nullptr), s(s0)
- {
- std::cout << "T(const s& s): s = " << shorten(s) << std::endl;
- }
- explicit T(std::string&& s0):
- tmp(nullptr), s(s0)
- {
- std::cout << "T(s&& s): s = " << shorten(s) << std::endl;
- }
- T(const T& t):
- tmp(nullptr), s(t.s)
- {
- std::cout << "T(const T& t): s = " << shorten(s) << std::endl;
- }
- T(T&& t):
- tmp(t.s.c_str()),
- s(std::move(t.s)) // No t from now. If we try to access t.s below, std::string does not move, it reallocates
- {
- const void *cs = s.c_str();
- std::cout << "T(T&& t): s = " << shorten(s) << "; ptrs = " << cs << " <- " << tmp << std::endl;
- }
- virtual ~T()
- {
- std::cout << "~T(): s = " << shorten(s) << std::endl;
- }
- };
- T f1()
- {
- T t = T("t within f1");
- std::cout << "f1: t contains: " << t.s << " at " << ((void *)(t.s.c_str())) << std::endl;
- return t;
- }
- int main()
- {
- // (1) move constructor called ONLY when compiling with: VC without optimizations and G++/CLang with -fno-elide-constructors
- T t1 = f1();
- std::cout << "t0 contains " << t1.s << " at " << ((void *)(t1.s.c_str())) << std::endl;
- // (2) move constructor called ONLY when compiling with: VC (all options) and G++/CLang with -fno-elide-constructors
- T t2 = T(T("t2"));
- // (3) move constructor is called ALWAYS (all compilers, all options)
- T t3 = T(std::move(T("t3")));
- // test other constructors
- T t5 = T("123");
- T t6 = t5;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement