Почему операции string :: append ведут себя странно? - PullRequest
0 голосов
/ 09 февраля 2010

посмотрите на следующий простой код:

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

int main()
{
    string s("1234567890");
    string::iterator i1 = s.begin();
    string::iterator i2 = s.begin();
    string s1, s2;
    s1.append(i1, ++i1);
    s2.append(++i2, s.end());

    cout << s1 << endl;
    cout << s2 << endl;
}

что вы ожидаете получить?

Вы, как и я, ожидаете, что это будет:

1
234567890

неправильно! это:

234567890

т.е. первая строка пуста.

показывает, что префиксный оператор приращения проблематичен для итераторов. или я что-то упустил?

Ответы [ 4 ]

14 голосов
/ 09 февраля 2010

Вы что-то упускаете: это действительно не имеет ничего общего с итераторами. Порядок, в котором оцениваются аргументы функции, не указан. Таким образом, ваше: append(i1, ++i1); будет зависеть от неопределенного поведения, независимо от типа i1. Просто, например, учитывая что-то намного проще, как:

void print(int a, int b) { 
    std::cout << a << " " << b << "\n";
}

int main() { 
    int a =0;
    print(a, ++a);
    return 0;
}

Ваш вывод вполне может быть «0 1», который вы ожидаете, но также вполне может быть: «1 1». Поскольку это не определено, он может измениться от одной версии компилятора к другой, или даже с тем же компилятором, когда вы меняете флаги, или (теоретически) может меняться в зависимости от фазы луны ...

8 голосов
/ 09 февраля 2010

C ++ реализации могут свободно оценивать аргументы в любом порядке. В этом случае, если ++ i1 вычисляется первым, вы получите пустую строку.

3 голосов
/ 09 февраля 2010

Не ошибка.

Порядок, в котором аргументы

s1.append(i1, ++i1);

оцениваются не указано в стандарте. Компилятор может использовать любой порядок по своему выбору. В этом случае он оценивает второй аргумент (++i1) перед первым (i1) и указывает нулевой диапазон для копирования.

3 голосов
/ 09 февраля 2010

Стандарт C ++ ничего не определяет в порядке, в котором оцениваются аргументы функции, что делает его зависимым от реализации. C ++ требует, чтобы аргументы функции были полностью оценены (и опубликованы все побочные эффекты) до входа в функцию, но реализация может свободно оценивать аргументы в любом порядке

В вашем случае i++ был оценен перед тем, как сделать оба параметра одинаковыми, в результате чего получилась пустая строка.

Больше информации об этом поведении здесь в новостная группа comp.compilers

...