【问题标题】:Can assignment from a const_iterator dereference cause undefined behaviour?来自 const_iterator 取消引用的赋值会导致未定义的行为吗?
【发布时间】:2015-09-09 08:05:35
【问题描述】:

此代码是对我在其他地方真正尝试做的事情的简化测试。我有一个函数,它接受一个“ref-to-ptr”参数并修改它以从指针列表中返回一个指针。

#include <iostream>
#include <list>
using namespace std;

typedef int* intp;
typedef std::list<intp> intplist;
intplist myList;

void func(intp &arg) // (1)
{
    intplist::const_iterator it = myList.begin();
    std::advance(it, 2);
    arg = *it;
}

int main()
{
    myList.push_back(new int(1));
    myList.push_back(new int(2));
    myList.push_back(new int(3));

    int* ip = NULL; // (2)
    func(ip);
    if (ip) cout << "ip = " << *ip << endl;
    else cout << "ip is null!" << endl;

    for (intplist::const_iterator it = myList.begin(); it != myList.end(); ++it) 
        delete *it;
    return 0;
}

它按预期工作并打印ip = 3,只是我担心它可能会导致未定义的行为或以其他方式导致麻烦,因为我通过将其取消引用的结果分配给参数来剥离迭代器的常量.我尝试在 (1) 和 (2) 处添加 const,但没有生成。

我担心是对的吗?如果是这样,为什么我没有收到来自 g++ (4.9.2) 的警告?

【问题讨论】:

  • “我尝试在 (1) 和 (2) 处添加 const,但没有构建。”:您是否也将 const 添加到 intp typedef?
  • 不...我将 typedef 视为愚蠢的字符串替换宏,只是将 const 放在 func 声明中:void func(const intp &amp;arg)。你的方式,它可以构建和工作,但我不明白有什么区别。
  • intp 是一个指针。 const intp 是常量指针,它没有说明它指向的值的常量性。当你说typedef const int* intp 时,你说它将指向一个 const 整数。
  • @neuviemeporte typedef 不是文本替换,它是类型的语义名称。 const intp &amp; 是对常量 intp 的引用 - 它是 int * const &amp;
  • @neuviemeporte 做什么? “注入”constvalue_type 如果它是一个指针?为此,您可以尝试std::add_pointer_t&lt;std::add_const_t&lt;std::remove_pointer_t&lt;typename T::value_type&gt;&gt;&gt;

标签: c++ pointers pass-by-reference undefined-behavior const-iterator


【解决方案1】:

代码非常好。你没有剥离任何常量(在 C++ 中没有办法隐式地做到这一点)。 *it 给你一个const intp &amp;。您正在将该引用所引用的指针复制arg。从某些东西复制并不会剥夺 constness。在您的情况下,对arg 的分配分配给ip,它不会绑定任何东西直接到容器内的intp 对象。

【讨论】:

  • 如果我没看错,这意味着*it 是“对指向 const int 的指针的引用”。我如何能够将其分配给val,即“对指向 int 的指针的引用”(非常量)?
  • 好的,我想我现在明白了——它是“对指针的常量引用”,对吧?指针从来都不是 const。
  • @neuviemeporte 是的,它是“对 a (constant (pointer to int)) 的引用”。数学意义上的括号。
【解决方案2】:

const_iterator 只是意味着您不能分配给该迭代器和/或只能在它指向的对象上调用 const 函数。复制value 没有问题 - 在这种情况下是指针。你没有存储 const 指针,如果你是,那么你将不得不分配给一个 const 指针

【讨论】:

    猜你喜欢
    • 2014-08-11
    • 2016-09-04
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多