The following code compiles and prints: move move. I would prefer that it didn't compile since merge takes rvalue references and I don't move t1 and t2 to it.
class A {
   public:
    A() = default;
    A(const A& other) { std::cout << "copy "; };
    A(A&& other) { std::cout << "move "; };
};
template <typename... TupleType>
auto merge(TupleType&&... tuples) {
    return std::tuple_cat(std::move(tuples)...);
}
int main() {
    std::tuple<int> t1{1};
    std::tuple<A> t2{A()};
    auto t3 = merge(t1, t2);
}
I'm not sure what happens here and why. Furthermore, I think this behavior is dangerous: I have no move in the call to merge, but t1 and t2 are moved from.
Why is this allowed and how can I make merge take only rvalue references?
 
    