C ++ 17在编译时将带有已删除副本构造函数的类添加到std :: vector

下面是我用删除的副本构造函数和副本赋值运算符定义的类。这是唯一必须做的假设。

class MyClass
{
    public:
    explicit MyClass(int i) : i(i) {}

    MyClass(const MyClass&) = delete;
    MyClass& operator=(const MyClass&) = delete;

    MyClass(MyClass&& other) :
        i(std::move(other.i))
        {}  

    MyClass& operator=(MyClass&& other) {
        i = std::move(other.i);
        return *this;
    }   

    private:
    int i;
};

然后的目标是在编译时将我的类添加到std :: vector。

int main()
{
    std::vector<MyClass> v{MyClass{0},MyClass{1},MyClass{2}};

    return 0;
}

我的编译器告诉我STL需要使用已删除的副本构造函数MyClass::MyClass(const MyClass&),但是有什么办法解决这个问题?

我已经知道在运行时添加值的一种可能方法,但是我认为以下方法是一个较差的解决方案,因为我丢失了编译时间检查。

int main()
{
    std::vector<MyClass> v;
    v.emplace_back(MyClass{0});
    v.emplace_back(MyClass{1});
    v.emplace_back(MyClass{2});

    return 0;
}
jinnaying 回答:C ++ 17在编译时将带有已删除副本构造函数的类添加到std :: vector

  

我的编译器告诉我STL需要使用已删除的副本构造函数MyClass::MyClass(const MyClass&),但是有什么办法解决这个问题?

不,您不能。

initializer_list为您创建一个隐藏数组,其声明为const,其估算如下:

// pseudo code
const MyClass __arr[3] = { MyClass(1),MyClass(2),MyClass(3) };
std::vector<MyClass> v{ std::initializer_list<MyClass>{ __arr,__arr + 2 } }; 

如果要避免复制,则必须按照您说的那样坚持使用emplace_back

  

我已经知道在运行时添加值的可能方法...

顺便说一句,您给出的示例不是不是使用emplace_back的正确方法:

std::vector<MyClass> v;
v.emplace_back(MyClass{0});
v.emplace_back(MyClass{1});
v.emplace_back(MyClass{2});

您仍在创建MyClass,然后将其移至v,这在使用emplace-ish函数时是很常见的错误。

您真正想做的可能是:

v.reserve(3);
v.emplace_back(0);
v.emplace_back(1);
v.emplace_back(2);

通过这种方式,您可以避免偶然调用move构造函数,而只需在正确的位置一次构造对象,并且没有移动

>
  

然后的目标是在编译时将我的类添加到std::vector中。

如果要在编译时创建数组,请改用std::arraystd::array正是为此目的而设计的:

std::array<MyClass,3> v = { 1,2,3 };
本文链接:https://www.f2er.com/3148313.html

大家都在问