Есть ли способ избежать вызова конструктора и деструктора для идеальной пересылки в функцию? - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь передать буквальное значение идеальному установщику переадресации, но вместо этого это приводит к созданию, перемещению и разрушению объекта. Я ищу более эффективный способ сделать это.

struct TStruct {
    TStruct(int va) : a(va) {
        std::cout << "- TStruct(" << va << ")" << std::endl;
    }
    TStruct(const TStruct& other) :
        a(other.a)
    {
        std::cout << "- TStruct(const TStruct& )" << std::endl;
    }
    TStruct(TStruct&& other) :
        a(std::exchange(other.a, 0))
    {
        std::cout << "- TStruct(const TStruct&&)" << std::endl;
    }
    TStruct& operator=(const TStruct& rhs) {
        std::cout << "- TStruct operator= const& " << std::endl;
        // check for self-assignment
        if(&rhs == this) return *this;
        a = rhs.a;
        return *this;
    }
    TStruct& operator=(TStruct&& rhs) {
        std::cout << "- TStruct operator=&&" << std::endl;
        // check for self-assignment
        if(&rhs == this) return *this;
        a = std::exchange(rhs.a, 0);
        return *this;
    }
    ~TStruct() {
        std::cout << "~ TStruct() destructor with " << a << std::endl;
    }
    int a = 1;
};

struct TPerfectForward {
    template<class T>
    TPerfectForward(T&& tsv) : ts(std::forward<T>(tsv)) {}

    template<class T>
    void set(T&& tsv) { ts = std::forward<T>(tsv); }

    TStruct ts;
};

std::cout << "TPerfectForward (5)" << std::endl;
TPerfectForward pf(5);

std::cout << "TPerfectForward set(4)" << std::endl;
pf.set(4);

Это дает следующие результаты с gcc 7.4.0 в Ubuntu:

TPerfectForward (5);
- TStruct(5)
TPerfectForward set(4)
- TStruct(4)
- TStruct operator=&&
~ TStruct() destructor with 0

Я хотел бы получить эти результаты лучше:

TPerfectForward (5)
- TStruct(5)
TPerfectForward set(4)
- TStruct(4)

Есть ли способ избежать вызова оператора перемещения и деструктора при совершенной пересылке в функцию?

...