Przemek Kryger
Przemek Kryger

Reputation: 687

C++ perfect forward copy-only types to make_tuple

I'm playing with this little snippet:

#include <tuple>

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

template <typename ...Ts>
void foo(Ts&& ...xs)
{
    auto t = std::make_tuple(std::forward<Ts>(xs)...);
    (void) t;
}

int main()
{
   foo(copy_only{});
}

It compiles fine with gcc7 and clang3.6, clang3.7, clang3.8 (Wandbox), and clang8.0 (macOS Sierra). It doesn't compile with clang3.9, g++6.2 (macOS Sierra) nor with clang4.0 (Wandbox). All of them complain about deleted move constructor.

It works fine with move-only types. At least on the above compilers available on Wandbox.

Is this code an example of a correct way of generic perfect forwarding into a tuple in c++14?

Upvotes: 3

Views: 1350

Answers (1)

krzaq
krzaq

Reputation: 16421

    auto t = std::make_tuple(std::forward<Ts>(xs)...);

This is indeed a correct way of forwarding arguments into a tuple.

The compile errors you get are caused by explicitly declaring copy_only's move constructor as deleted. Normally, if you declared a copy constructor, it'd be omitted and in move contexts the copy constructor would be chosen - as it has since C++98. But because you explicitly declared it, it does participate in the overload resolution and causes the code to be ill-formed if selected.

Here's a helpful chart courtesy of Howard Hinannt: chart

This can be solved by removing the offending line from the class definition:

struct copy_only
{
    copy_only() = default;
    //copy_only(copy_only&&) = delete;
    copy_only(const copy_only&) = default;
};

Now, as to whether your code should compile or not: as far as I can tell, it should. tuple's move constructor is defined as:

tuple(tuple&& u) = default;

Requires: is_move_constructible<Ti>::value is true for all i.

Since copy_only is not move constructible, it shouldn't be declared and shouldn't participate in overload resolution.

Upvotes: 2

Related Questions