lundi 5 août 2019

How can I initialize non-static private template member variables from temporaries in-place, i.e., without making a copy or move?

I'd like to initialize two non-static private template member variables of a class template from a temporary in-place, i.e., without making a copy or move.

For clarification, consider the following example code:

#include <iostream>

struct P {
    P(int n) : n_ { n } {};

    P(P&&) { std::cout << "P:moved" << std::endl; }
    P(const P&) { std::cout << "P:copied" << std::endl; }

    int n_;
};

struct Q {
    Q(double x) : x_ { x } {};

    Q(Q&&) { std::cout << "Q:moved" << std::endl; }
    Q(const Q&) { std::cout << "Q:copied" << std::endl; }

    double x_;
};

/* note that P and Q are just two illustrative examples;
   don't count on anything specific in them; with respect
   to the asked question, they should just represent two
   arbitrary classes with arbitrary ctors */

template<typename U, typename V>
class X {
    public:
        X(U u, V v) : u_ { u }, v_ { v } {}

    private:
        U u_;
        V v_;
};

int
main(
) {
    X x { P { 0 }, Q { 0.0 } };

    return 0;
}

Output (with gcc 8.2.0) is P:copied Q:copied because u and v are copied to u_ and v_ in X's ctor, respectively. However, since the temporaries P { 0 } and Q { 0.0 } are only used to initialize u_ and v_, respectively, I wonder whether one can initialize both member variables in-place. I'd like to see neither copied nor moved here. Even more, I'd like to run this code with copy and move ctor of P and Q deleted.

Is this possible in C++17 (or earlier), and if so, how?

Aucun commentaire:

Enregistrer un commentaire