如何创建不可复制对象的元组

问题描述 投票:0回答:2

我正在尝试创建一个不可复制对象的元组。当我有了复制构造函数时,我就可以构造元组了。当它们被删除时,编译失败。

#include <tuple>
#include <iostream>
#include <utility>

struct A {
    int& x;
    int& y;

    A(int& a, int& b) : x(a), y(b) {}
    A(const A&) = delete;
    A& operator=(const A&) = delete;
};

class B {
public:
    B(int& w, int& x, int& y, int& z)
    : a_b_{ A(w,x),A(y,z)} {}
    
private:
    std::tuple<A, A> a_b_;
};

int main() {
    int w =1, x=2, y=3, z=4;
    B b{w,x,y,z};
    return 0;
}

我能够通过添加一个元组构造函数来实现它。

struct A {
    int& x;
    int& y;

    A(int& a, int& b) : x(a), y(b) {}
    A(const A&) = delete;
    A& operator=(const A&) = delete;

    
    template<typename ...Args>
    A(const std::tuple<Args...> &args)
        : A(args, std::index_sequence_for<Args...>{}) {}

    template<typename ...Args, std::size_t ...Is>
    A(const std::tuple<Args...> &args, std::index_sequence<Is...>)
        : A(std::get<Is>(args)...) {}


};

class B {
public:
    B(int& w, int& x, int& y, int& z)
    : a_b_{ std::forward_as_tuple(w,x), std::forward_as_tuple(y,z)} {}
    
private:
    std::tuple<A, A> a_b_;
};

这并不理想,因为它需要将此构造函数添加到我的所有类中。有没有不需要改变元组中对象的解决方案?谢谢!

c++ tuples c++17
2个回答
0
投票

C++17 中有一种方法。在 C++11/14 中不起作用,因为在 C++17 中 RVO 是强制性的。

它需要一个用于构造

C
的中间类
A
。在 C++17 之前的版本中,您必须向
A
.

添加一个额外的构造函数
#include <tuple>
#include <iostream>
#include <utility>

struct A {
    int& x;
    int& y;

    A(int& a, int& b) : x(a), y(b) {}
    A(const A&) = delete;
    A& operator=(const A&) = delete;
};

struct C {
    int* x;
    int* y;
    
    C(int& a, int& b) : x(&a), y(&b) {};
    
    operator A () const
    {
        return A(*x,*y);
    }
};

class B {
public:
    B(int& w, int& x, int& y, int& z)
    : a_b_{ C{w,x}, C{y,z}} {}
    
private:
    std::tuple<A, A> a_b_;
};

int main() {
    int w =1, x=2, y=3, z=4;
    B b{w,x,y,z};
    return 0;
}

如果您要使用

std::pair
而不是
std::tuple
,您也可以通过
std::piecewise_construct
来实现它。看,

#include <tuple>
#include <iostream>
#include <utility>

struct A {
    int& x;
    int& y;

    A(int& a, int& b) : x(a), y(b) {}
    A(const A&) = delete;
    A& operator=(const A&) = delete;
};


class B {
private:
    std::pair<A, A> a_b_;
public:
    B(int& w, int& x, int& y, int& z)
    : a_b_{std::piecewise_construct, std::forward_as_tuple(w,x),  std::forward_as_tuple(y,z)} {}
};

int main() {
    int w =1, x=2, y=3, z=4;
    B b{w,x,y,z};
    return 0;
}

0
投票

如果可以使用“对”而不是“元组”作为类

B
的私有数据成员,那么我们可以如下使用类标签
piecewise_construct_t
,而无需在类中进行任何更改
A
:

struct A {
    int& x;
    int& y;

    A(int& a, int& b) : x(a), y(b) {}
    A(const A&) = delete;
    A& operator=(const A&) = delete;
};

class B {
public:
    B(int& w, int& x, int& y, int& z)
    : a_b_{std::piecewise_construct, 
           std::forward_as_tuple(w,x), 
           std::forward_as_tuple(y,z)} {}
    
private:
    std::pair<A, A> a_b_;
};
© www.soinside.com 2019 - 2024. All rights reserved.