将结构复制到具有常量值的数组
Copy struct to array with const values
我正在尝试替换非 const 数组中具有 const 值但无法编译的结构值:
Object of type 'Foo' cannot be assigned because its copy assignment operator is implicitly deleted
这是一个例子:
struct Foo {
const int id;
int value;
Foo(): id(-1), value(-1) {}
Foo(int id): id(id), value(0) {}
};
int main(int argc, const char * argv[]) {
Foo foos[10];
foos[0] = Foo(1234);
return 0;
}
我来自 swift 背景,在该背景下有效,因为它将结构值复制到数组中。
我尝试制作我认为是复制赋值运算符的东西,但对于 const 成员,我尝试的东西也不起作用。
这就是我试图为复制赋值运算符做的事情:
Foo& operator= (Foo newVal) {
// what do I put here!?
return *this;
};
对数组进行 memcpy
工作但似乎用错了大锤。
作为 c++ 的新手,我不确定这种类型的流程的正确模式是什么。
在C++中,一个对象只能初始化一次。当您声明数组时,您的常量成员通过默认构造函数进行初始化。然后,您尝试通过赋值
更改该值
foos[0] = Foo(1234);
这失败了,这是正确的。你可以做的一件事是拥有一个不是 Foos 的容器,而是某种指向 foo 的指针。因此,您将为指针分配内存,但只会在可以时创建实际对象。例如:
Foo* foos[10]; //here you have only the pointers
foos[0] = new Foo(1234); //OK, the object is inialized here
您可以考虑使用 std::unique_ptr
等智能指针来代替原始指针。
C++ 非常严格地对待 const
。如果可能的话,复制这样的结构将是痛苦的(没有 UB)。也许您真正要寻找的是“只读”?在这种情况下,您可以使用 public getters/setters:
将字段设为私有
struct Foo {
public:
Foo(): id(-1), value(-1) {}
Foo(int id): id(id), value(0) {}
int getId() const {
return id;
}
int getValue() const {
return value;
}
void setValue(int newValue) {
value = newValue;
}
private:
int id;
int value;
};
const
值在初始化后永远无法更改。
从名称 id
听来,move 语义正是您所需要的。您可以 移动 对象之间的数据,而不是 复制 ,而不是让两个有效对象具有相同的 id
]它。
示例:
#include <iostream>
#include <utility>
struct Foo {
Foo() : id(-1), value(-1) {} // default - "invalid" values
Foo(int id, int value) : id(id), value(value) {} // constructor
explicit Foo(int id) : Foo(id, 0) {} // converting ctor, delegating
Foo(const Foo&) = delete; // no copy construction
Foo(Foo&& rhs) : // move construction ok
id(std::exchange(rhs.id, -1)), // take id, give -1 back
value(std::exchange(rhs.value, -1)) // take value, give -1 back
{}
Foo& operator=(const Foo&) = delete; // no copy assignment
Foo& operator=(Foo&& rhs) { // move assignment ok
// give the "moved from" element our id and value and
// take id and value from the "moved from" element
std::swap(id, rhs.id);
std::swap(value, rhs.value);
return *this;
}
int Id() const { return id; } // only const access
int& Value() { return value; } // non-const access in non-const context
int Value() const { return value; } // const access in const context
private:
int id;
int value;
};
int main() {
Foo foos[2];
foos[0] = Foo(1234); // The temporary Foo will have (-1, -1) when it's destroyed
for(auto& f : foos)
std::cout << f.Id() << ' ' << f.Value() << '\n';
}
输出:
1234 0
-1 -1
时代,C++标准变了!
您现在可以为 类 定义自己的 copy-assignment 运算符,其中包含 const 成员对象,自 c++20 起没有未定义的行为。
这是 c++ 之前的未定义行为,对于完整的 const 对象仍然如此,但 non-const 具有 const 成员的对象则不然。
我正在尝试替换非 const 数组中具有 const 值但无法编译的结构值:
Object of type 'Foo' cannot be assigned because its copy assignment operator is implicitly deleted
这是一个例子:
struct Foo {
const int id;
int value;
Foo(): id(-1), value(-1) {}
Foo(int id): id(id), value(0) {}
};
int main(int argc, const char * argv[]) {
Foo foos[10];
foos[0] = Foo(1234);
return 0;
}
我来自 swift 背景,在该背景下有效,因为它将结构值复制到数组中。
我尝试制作我认为是复制赋值运算符的东西,但对于 const 成员,我尝试的东西也不起作用。
这就是我试图为复制赋值运算符做的事情:
Foo& operator= (Foo newVal) {
// what do I put here!?
return *this;
};
对数组进行 memcpy
工作但似乎用错了大锤。
作为 c++ 的新手,我不确定这种类型的流程的正确模式是什么。
在C++中,一个对象只能初始化一次。当您声明数组时,您的常量成员通过默认构造函数进行初始化。然后,您尝试通过赋值
更改该值foos[0] = Foo(1234);
这失败了,这是正确的。你可以做的一件事是拥有一个不是 Foos 的容器,而是某种指向 foo 的指针。因此,您将为指针分配内存,但只会在可以时创建实际对象。例如:
Foo* foos[10]; //here you have only the pointers
foos[0] = new Foo(1234); //OK, the object is inialized here
您可以考虑使用 std::unique_ptr
等智能指针来代替原始指针。
C++ 非常严格地对待 const
。如果可能的话,复制这样的结构将是痛苦的(没有 UB)。也许您真正要寻找的是“只读”?在这种情况下,您可以使用 public getters/setters:
struct Foo {
public:
Foo(): id(-1), value(-1) {}
Foo(int id): id(id), value(0) {}
int getId() const {
return id;
}
int getValue() const {
return value;
}
void setValue(int newValue) {
value = newValue;
}
private:
int id;
int value;
};
const
值在初始化后永远无法更改。
从名称 id
听来,move 语义正是您所需要的。您可以 移动 对象之间的数据,而不是 复制 ,而不是让两个有效对象具有相同的 id
]它。
示例:
#include <iostream>
#include <utility>
struct Foo {
Foo() : id(-1), value(-1) {} // default - "invalid" values
Foo(int id, int value) : id(id), value(value) {} // constructor
explicit Foo(int id) : Foo(id, 0) {} // converting ctor, delegating
Foo(const Foo&) = delete; // no copy construction
Foo(Foo&& rhs) : // move construction ok
id(std::exchange(rhs.id, -1)), // take id, give -1 back
value(std::exchange(rhs.value, -1)) // take value, give -1 back
{}
Foo& operator=(const Foo&) = delete; // no copy assignment
Foo& operator=(Foo&& rhs) { // move assignment ok
// give the "moved from" element our id and value and
// take id and value from the "moved from" element
std::swap(id, rhs.id);
std::swap(value, rhs.value);
return *this;
}
int Id() const { return id; } // only const access
int& Value() { return value; } // non-const access in non-const context
int Value() const { return value; } // const access in const context
private:
int id;
int value;
};
int main() {
Foo foos[2];
foos[0] = Foo(1234); // The temporary Foo will have (-1, -1) when it's destroyed
for(auto& f : foos)
std::cout << f.Id() << ' ' << f.Value() << '\n';
}
输出:
1234 0
-1 -1
时代,C++标准变了!
您现在可以为 类 定义自己的 copy-assignment 运算符,其中包含 const 成员对象,自 c++20 起没有未定义的行为。
这是 c++ 之前的未定义行为,对于完整的 const 对象仍然如此,但 non-const 具有 const 成员的对象则不然。