c++ 17在编译时将具有已删除复制构造函数的类添加到std::vector

标签 c++ vector c++17 copy-constructor move-semantics

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

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;
}

最佳答案

My compiler is telling me that the STL requires the use of my deleted copy constructor MyClass::MyClass(const MyClass&) but is there any way around this?

不,你不能。

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

I am already aware of a possible way to add values at runtime ...

顺便说一句,您的示例不是 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 构造函数,而只是在正确的位置构造对象只有一次,没有 move ,也没有复制

The goal is then to add my class to a std::vector at compile time.

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

std::array<MyClass, 3> v = { 1, 2, 3 };

关于c++ 17在编译时将具有已删除复制构造函数的类添加到std::vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58740022/

相关文章:

c++ - OLE bstr 不以 null 终止?

c++ - 检查 Gdiplus::Bitmap::FromFile 是否返回了有效的位图

python - np.linalg.qr(A) 或 scipy.linalg.orth(A) 用于查找正交基(python)

Matlab:如何根据索引向量将1填充到零向量?

c++ - 如何声明和定义具有推导类型的静态成员?

c++ - std::string_view 和 std::string in std::unordered_set

c++ - 在循环中创建一个对象

c++ - 字符串到枚举模板错误

c++ - 这是使用点积求两个 vector 之间角度的正确方法吗? C++ SFML

c++ - 是否可以在编译时连接两个 `const char *` 类型的字符串?