English 中文(简体)
Why are string::append operations behaving strangely?
原标题:

look at the following simple code:

#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;
}

what would you expect the output to be?

would you, like me, expect it to be:

1
234567890

wrong! it is:

234567890

i.e. the first string is empty.

seams that prefix increment operator is problematic with iterators. or am I missing something?

最佳回答

Not a bug.

The order in which the arguments to

s1.append(i1, ++i1);

are evaluated is not specified by the standard. The compiler is free to use any order it chooses. In this case, it evaluates the second argument (++i1) before the first (i1) and you specify a null range to copy.

问题回答

You re missing something: this really has nothing to do with iterators. The order in which arguments to a function are evaluated is unspecified. As such your: append(i1, ++i1); would depend on unspecified behavior, regardless of the type of i1. Just for example, given something a lot simpler like:

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

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

Your output could perfectly reasonably be the "0 1" you seem to expect, but it could also perfectly reasonably be: "1 1". Since this is unspecified, it could change from one version of the compiler to the next, or even with the same compiler when you change flags, or (in theory) could vary depending on the phase of the moon...

C++ implementations are free to evaluate arguments in any order. In this case, if ++i1 is evaluated first, you will get an empty string.

The C++ standard does not specify anything about the order in which the function arguments are evaluated, making it implementation dependent. C++ requires that the arguments to a function be completely evaluated (and all side-effects posted) prior to entering the function, but the implementation is free to evaluate the arguments in any order

In your case i++ got evaluated before making both the parameters same, resulting in an empty string.

More info on this behavior here on comp.compilers newsgroup





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签