mercredi 28 octobre 2015

Why does initialization of my object with variadic template arguments requires the definition of move constructor?

I want to create a local object of some type provided to the template parameter of some function:

template <typename Type, typename... Args>
void create_local(Args... args)
{
    Type val(args...);
}

Now, when I call this function with no arguments (where Type is a class with a non-copyable member):

struct T {
    std::mutex m;
};

int main()
{
    T t;               // OK: No use of move constructor
    create_local<T>(); // Error: Requires deleted move constructor!!!
}

(coliru link)

g++ (from 4.7.3 to 5.2) fails to compile and requires the definition of the move constructor of T? clang 3.7 compiles successfully.

Additionally, if I (1) remove std::mutex member from T, (2) declare default constructor for T, and (3) declare a deleted copy-constructor for T:

struct T {
    T() = default;
    T(const T&) = delete;
};

template <typename Type, typename... Args>
void create_local(Args... args)
{
    Type val(args...);
}

int main()
{
    T t;               // OK: No use of move constructor
    create_local<T>(); // OK: No use of move constructor
}

all versions of g++ and clang compiles successfully. Why does g++ not compile for any type Type with non-copyable members?

Aucun commentaire:

Enregistrer un commentaire