假设我有一个这样的结构。让结构的一个成员指向它内部的另一个成员合法吗?这些是如何储存的?
struct Foo {
int m1{};
int m2{};
int* pint{};
std::string str{};
const char* pstr{};
};
我先设置成员,然后再设置指针。这合法吗?
Foo a {
.m1 = 10,
.m2 = 15,
.str = "Hello, Earth!"
};
a.pint = &a.m1;
a.pstr = a.str.c_str();
我先设置指针,然后再设置成员。这合法吗?
Foo a {};
a.pint = &a.m1;
a.pstr = a.str.c_str();
a.m1 = 10,
a.m2 = 15,
a.str = "Hello, Earth!"
我在Godbolt.org上查看了一下,它似乎即使在最高优化级别也能工作,但我想确保它是合法的C++,以免UB海怪吞噬我的程序。
有没有一种方法我可以聚合初始化内联到结构成员的指针?像这样的东西?
Foo a {
.m1 = 10,
.m2 = 15,
.pint = // address to m2?
.str = "Hello, Earth!",
.pstr = // something.c_str()?
};
p.S.我该如何表达这个问题,寻找指向内部成员(和变体(的结构成员没有产生任何有用的结果。
编辑:我知道复制/移动因此而中断。对答复者的请求。如果可能的话,请给我指一下说明书,这样我就可以养成正确阅读和解释说明书的习惯。
这是合法的,但默认的复制/移动操作已中断。
要么添加
Foo(Foo const&)= delete;
Foo(Foo&&)=delete;
Foo&operator=(Foo const&)= delete;
Foo&operator=(Foo&&)=delete;
或者实施它们来做一些明智的事情。
基于注释
不,成员总是指向其他成员(如果有的话(。
我建议将成员变量pint
和pstr
从指向对象的指针更改为指向成员变量的指针。
struct Foo {
int m1{};
int m2{};
std::string str{};
int Foo::* pint{nullptr};
std::string Foo::* pstr{nullptr};
};
然后,您可以毫无问题地使用默认的复制构造函数和复制赋值运算符。以下内容应该有效。
Foo a {10, 15, "Hello, Earth!", &Foo::m1, &Foo::str};
std::cout << a.*(a.pint) << std::endl;
std::cout << a.*(a.pstr) << std::endl;
// Default copy constructor works fine.
Foo b = a;
std::cout << b.*(b.pint) << std::endl;
std::cout << b.*(b.pstr) << std::endl;
// Default copy assignment works fine.
Foo c;
c = a;
std::cout << c.*(c.pint) << std::endl;
std::cout << c.*(c.pstr) << std::endl;
看到它在工作https://ideone.com/qE1WVn.
Re:
你能回答问题的最后一部分吗(聚合初始化指向结构成员的内联指针(?
您也可以使用
struct Foo {
int m1{};
int m2{};
std::string str{};
int Foo::* pint{&Foo::m1};
std::string Foo::* pstr{&Foo::str};
};
和
Foo a {
.m1 = 10,
.m2 = 15,
.str = "Hello, Earth!",
.pint = &Foo::m2,
.pstr = &Foo::str
};