提问人:Jonathan Mee 提问时间:9/24/2015 最后编辑:CommunityJonathan Mee 更新时间:9/24/2015 访问量:499
奇异迭代器的赋值
Assignment of a Singular Iterator
问:
“奇异迭代器”被定义为:
不与任何序列关联的迭代器。空指针以及默认构造的指针(包含不确定值)是单数
我的问题 1 是:默认构造的迭代器是否被视为“奇异迭代器”?
其次,我在这里被告知:
对于奇异值,大多数表达式的结果都是未定义的;唯一的例外是销毁包含奇异值的迭代器,将非奇异值分配给包含奇异值的迭代器,以及对于满足 DefaultConstructible 要求的迭代器,使用值初始化的迭代器作为复制或移动操作的源。
问题 2 是:使用“未定义”的结果是否构成未定义行为?如果这是真的,这似乎是未定义的行为:
void* foo = nullptr;
auto bar = foo;
我问这个问题的更深层次的动机是,我有一个这样的结构:
struct Foo {
vector<int*>::const_iterator;
};
我想知道这样做是否是未定义的行为,其中值构造对象:assigned
Foo
Foo unasigned;
assigned = unassigned;
如果问题 1 和 2 的答案是“是”,那么通过调用默认赋值运算符,我将引入未定义的行为:(
答:
0赞
CinCout
9/24/2015
#1
问题 2 是:使用“未定义”的结果是否构成未定义行为?
答案是:绝对是的。在 UB 上工作是 UB。
它似乎对您来说运行良好,因为它是未定义的。它可以做任何事情,包括按预期工作,以及不按预期工作。
0赞
Some programmer dude
9/24/2015
#2
关于第二个问题的示例,它工作正常,因为并且定义明确,因为您实际上并没有取消引用指针。变量已初始化,您所要做的就是使用另一个初始化的变量初始化一个变量。这与例如没有什么不同foo
foo
int foo = 0;
auto bar = foo;
但是,如果您这样做,例如
int* foo = nullptr;
auto bar = *foo;
这将是 UB,因为您取消了对空指针的引用。
此外,未定义的行为是,嗯,未定义......它可能看起来运行良好,但实际上并非如此。
评论
0赞
Jonathan Mee
9/24/2015
对,我不需要取消引用我的结构成员的内容,所以我认为这意味着它也定义得很好?vector<int*>::const_iterator
1赞
Some programmer dude
9/24/2015
@JonathanMee 没错,如果你有一个默认初始化的迭代器,它仍然会初始化,你可以将其用作赋值的源。当您尝试执行任何其他操作(包括不仅仅是取消引用)时,您就会获得 UB。
0赞
Jonathan Mee
9/24/2015
我想相信这句话,因为它简化了我在代码中的很多问题。但是这种说法与我在问题中的第二句话相冲突,不是吗?(虽然也许这句话已经过时了?我刚刚读到这个:en.cppreference.com/w/cpp/concept/......)
1赞
T.C.
9/26/2015
@JoachimPileborg 编号在 中,是默认初始化的,但根据适用的核心语言规则是 UB。这就是迭代器子句需要值初始化迭代器的原因。int *x, *y;
x
y = x;
评论
vector<int*>::const_iterator foo;
vector<int*>::const_iterator