3
#include <string>
#include <iostream>

int main()
{
    std::string test("hello world ");
    std::string label("label test");
    test.append(&label[3]);    //----- #1
    std::cout << test << std::endl;
}

for the above code, what I expected is "hello world e", but in fact, its output is "hello world el test". It append all the characters after position 3 to my string test.

At the position #1, if I don't put the & sign, there will be compilation error:

str_append.cpp:10:10: error: no matching member function for call to 'append'
    test.append(label[3]);
    ~~~~~^~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:1516:19: note: candidate function not viable: no known conversion
      from 'value_type' (aka 'char') to 'const value_type *' (aka 'const char *') for 1st argument; take the address of the argument with &
    basic_string& append(const value_type* __s);
                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:1513:19: note: candidate function not viable: no known conversion
      from 'value_type' (aka 'char') to 'const std::__1::basic_string<char>' for 1st argument
    basic_string& append(const basic_string& __str);
                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:1525:9: note: candidate function template not viable: requires 2
      arguments, but 1 was provided
        append(_InputIterator __first, _InputIterator __last);
        ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:1532:9: note: candidate function template not viable: requires 2
      arguments, but 1 was provided
        append(_ForwardIterator __first, _ForwardIterator __last);
        ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:1515:19: note: candidate function not viable: requires 2
      arguments, but 1 was provided
    basic_string& append(const value_type* __s, size_type __n);
                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:1517:19: note: candidate function not viable: requires 2
      arguments, but 1 was provided
    basic_string& append(size_type __n, value_type __c);
                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:1514:19: note: candidate function not viable: requires at least 2
      arguments, but 1 was provided
    basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
                  ^
1 error generated.

The only way i can solve this is to change the #1 line to :

test += label[3];

So, I want to know what the logic behind this? Can't label[3] return a single character? why it fails when i just use test.append(label[3]);. And why test += label[3]; succeeds?

Thanks in advance.

1
  • Yet another "I didn't read the documentation" question. What is wrong with the world? downvotes and cries Commented Oct 18, 2015 at 14:38

3 Answers 3

3

You aren't appending a character; you're appending a C-string. That C-string is provided by the pointer &label[3], which points to the following data: {'e','l',' ','t','e','s','t','\0'}.

To append a character you'd just pass label[3] itself. However, to do this you need to use basic_string& append(size_type count, CharT ch), or its convenient equivalent (when count==1), void push_back(CharT ch).

The operator+= is functionally analogous to push_back, which is why it worked when you tried it.

So:

#include <string>
#include <iostream>

int main()
{
    std::string test("hello world ");
    std::string label("label test");

    test.append(1, label[3]);  // or...
    test.push_back(label[3]);  // or...
    test += label[3];

    std::cout << test << std::endl;
}

In brief, read the documentation to find out what members std::string has, and how to use them.

Sign up to request clarification or add additional context in comments.

Comments

3

Because there is no std::basic_string::append() overload that takes a single character. See for yourself here.

Basically, std::basic_string::append() is not designed to add a single character to the back of a string, but characters. The std::basic_string::push_back() is designed for this purpose instead. Or you may just use operator + which is applicable to both a single character and characters.

On cppreference, the descriptions for each function are (emphasis mine):

  • append(): Appends characters to the end
  • push_back(): Appends a character to the end
  • operator +: Concatenates two strings or a string and a char

Comments

0

label[3] will return a single character (structly speaking, a reference of it), but unfortunately std::string doesn't have a function append that takes one character.

test.append('a'); also fails.

std::string has operator+= that takes one character, so test += label[3]; succeeds.

2 Comments

Actually, it is operator +. std::basic_string does not have a operator += overload.
@Lingxi N3337 says that basic_string has basic_string& operator+=(charT c); (21.4.6.1 basic_string::operator+=)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.