Search code examples
c++operator-overloadingoperatorsstring-literalssquare-bracket

How does this overloading of square brackets work


I want to avoid printing space (" ") or an underscore ("_") after the last element of an array while printing them using a for loop. The problem mentions one of the way to do so, I want to understand how and why this happens.

    vector<int> v1 = {1, 2, 3, 4, 5};
    int n = v1.size();
    for (int i = 0; i < n; i++) {
        cout << v1[i] << "_"[i==n-1];
    }

this prints 1_2_3_4_5 which is as expected.

I want to get around the working of this operator. How it functions and what other aspects does it cover.


Solution

  • There is nothing special going on with [] here. Its the usual element access. "_" is a const char [2] where first character is _ and the second is a null terminator \0.

    You could do the same with a string:

    vector<int> v1 = {1, 2, 3, 4, 5};
    int n = v1.size();
    for (int i = 0; i < n; i++) {
        cout << v1[i] << std::string{"_"}[i==n-1];
    }
    

    Note, that std::string is an excepetion among containers and it is ok to read the \0 from str[str.size()].

    \0 is not a printable character, hence you see the output you see.

    Perhaps the code more clear if you use an empty string explicitly:

    vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<std::string> d{ "_",""};
    int n = v1.size();
    for (int i = 0; i < n; i++) {
        cout << v1[i] << d[i==n-1];
    }
    

    Alternatively, as you are using an index based loop anyhow (rather than a range based loop, which should be prefered), you can start the loop at the second element:

    std::vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<std::string> d{ "_",""};
    int n = v1.size();
    if (n) std::cout << v1[0];
    for (int i = 1; i < n; i++) {
        std::cout << "_" << v1[i];
    }