How to find out or check if this type will be moved

I am not looking for a type type for movable types , but rules for automatically generating move operations . What I'm looking for is a general guide to know whether a given type will be moved or copied, or how it tests itself.

In some cases, the move operation is performed without notifying the user, for example:

void f(std::string) { ... }
void f_c(const std::string) { ... }

void g()
{
    f(std::string("Hello world!"));   // moved, isn't it?
    f("Hello world!");                // moved, isn't it?
    f_c(std::string("Hello world!")); // moved, isn't it?
    f_c("Hello world!");              // moved, isn't it?
}

Prior to C ++ 11, the above code would lead to std::stringcopying from a temporary value to the value passed to fand f_cfrom C ++ 11 and further std::basic_stringprovides a move constructor (see here (8) ), and the temporary created will be moved to the parameter passed to fand f_c.

std::move:

std::string return_by_value_1()
{
    std::string result("result);
    return std::move(result); // Is this moved or not?
}

std::string return_by_value_2()
{
    return std::move(std::string("result)); // Is this moved or not?
}

std::move 1: lvalues ​​ rvalues, : ... AFAIK std::move ing return_by_value_x RVO ( !).

, (, ) , :

, ?

:

int f_int(int) { ... };
template <typename F, typename S> void f_pair(std::pair<F, S>) { ... };

struct weird
{
    int i;
    float f;
    std::vector<double> vd;
    using complexmap = std::map<std::pair<std::string, std::uint64_t>, std::pair<std::uint32_t, std::uint32_t>>;
    complexmap cm;
};

struct silly
{
    std::vector<std::pair<const std::string, weird::complexmap>> vcm;
};

f_weird(weird) { ... };
f_silly(silly) { ... };

  • ? f_int, ?
    • f_int(1); // this moves or construct an int in-place?
    • f_int(1 + 2); // this moves or construct an int in-place?
    • f_int(f_int(1) + 2); // this moves or construct an int in-place?
  • , ?
    • f_pair<std::pair<const std::string, int>>({"1", 2}); // unmovable?
    • f_pair<std::pair<std::string, std::string>>({"1", "2"}); // this moves?
    • f_silly({{{}, {}}}); // this moves?
  • struct weird ?
    • f_weird({1, .0f, {0.d, 1.d}, {{{"a", 0ull}, {1u, 2u}}}}) // this moves?
  • , , ?

1 , std::rvalref - ?

+1
1

, , ?

, SFINAE. final. , , , ,

namespace detail {
  // No copy constructor. Move constructor not deleted if T has an applicable one.
  template <typename T>
  struct Test : T { Test(Test&&) = default; };
}

// TODO: Implement unions
template <typename T>
using is_moveable = std::is_move_constructible<
    std::conditional_t<std::is_class<T>{}, detail::Test<T>, T>>;

.

Test [dcl.fct.def.default]/5. , , [class.copy]/11:

[..] X (8.4.3), X :

  • M ( ) , [..] , (13.3), M s, , [..]

, , (13.3, 13.4).

Test(Test())

, ctor ​​, . , , Test (, , ), , T, . ( , T , .)

+1

All Articles