使用迭代器范围将单个元素附加到容器

时间:2022-07-20 10:06:30

I want to (copy) append single element to some (STL-like) container, but all I can use is basic_string & append(InputIt first, InputIt last)-like interface to initialize or to append elements to the container.

我想(复制)将单个元素附加到某个(类似STL的)容器,但我可以使用的是basic_string&append(InputIt first,InputIt last)-like接口来初始化或将元素附加到容器。

Is it wrong to do the following:

执行以下操作是错误的:

#include <vector>

struct container
{

    template< typename input_iterator >
    void init(input_iterator const beg, input_iterator const end)
    {
        v.insert(v.cend(), beg, end);
    }

    template< typename input_iterator >
    void append(input_iterator beg, input_iterator const end)
    {
        while (beg != end) {
            v.push_back(*beg);
            ++beg;
        }
    }

private:
    std::vector< int > v;
};

#include <cstdlib>

int main()
{
    int i = 123;
    container c;
    c.init(&i, &i + 1);
    int j = 555;
    c.init(&j, &j + 1);
    return EXIT_SUCCESS;
}

Specifically, I am concerned with whether the f(&i, &i + 1) construction is valid (assume unary operator & is not overloaded) or not?

具体来说,我关心f(&i,&i + 1)结构是否有效(假设一元运算符并且没有超载)?

1 个解决方案

#1


6  

Yes, it's perfectly valid. From [expr.unary.op]:

是的,它完全有效。来自[expr.unary.op]:

For purposes of pointer arithmetic (5.7) and comparison (5.9, 5.10), an object that is not an array element whose address is taken in this way is considered to belong to an array with one element of type T.

出于指针运算(5.7)和比较(5.9,5.10)的目的,不是以这种方式获取地址的数组元素的对象被认为属于具有T类型的一个元素的数组。

&i + 1 simply points to one past the end of that object, which for this purpose is one past the end of an array of size one of that type, which is a perfectly legal thing to refer to, according to [expr.add]:

&i + 1只指向一个超过该对象结尾的对象,为此目的是一个超过该类型的第一个数组的结尾,根据[expr.add],这是一个完全合法的引用。 :

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。


As a side note, your append() function is a strictly worse implementation of your init() function.

作为旁注,你的append()函数是init()函数的严格执行。

#1


6  

Yes, it's perfectly valid. From [expr.unary.op]:

是的,它完全有效。来自[expr.unary.op]:

For purposes of pointer arithmetic (5.7) and comparison (5.9, 5.10), an object that is not an array element whose address is taken in this way is considered to belong to an array with one element of type T.

出于指针运算(5.7)和比较(5.9,5.10)的目的,不是以这种方式获取地址的数组元素的对象被认为属于具有T类型的一个元素的数组。

&i + 1 simply points to one past the end of that object, which for this purpose is one past the end of an array of size one of that type, which is a perfectly legal thing to refer to, according to [expr.add]:

&i + 1只指向一个超过该对象结尾的对象,为此目的是一个超过该类型的第一个数组的结尾,根据[expr.add],这是一个完全合法的引用。 :

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。


As a side note, your append() function is a strictly worse implementation of your init() function.

作为旁注,你的append()函数是init()函数的严格执行。