charに文字列を連結する際の注意

#エラー再現
次のようなコードを記述した際に文章が途切れたエラーメッセージが出力されました。範囲外エラー的なエラーメッセージは出力されますが、その部分以外は正常に動いていました。
どうやら文字列にエラーメッセージが保管されている様子で、原因を探るために色々と実験してみました。
##コード

```c++:
#include <iostream>
#include <string>
#include <array>
#include <vector>
int main()
{
    std::array<std::string, 5> ary = {
        "ary01", "ary02", "ary03", "ary04", "ary05"
    };
    std::vector<std::string> vec = {
        "vec1", "vec2", "vec3"
    };
    std::string s_string_1 = vec.at(0).at(0) + ":" + ary.at(0);
    std::string s_string_2 = ary.at(0).at(0) + ":" + vec.at(0);

    std::cout << s_string_1 << std::endl;
    std::cout << s_string_2 << std::endl;
    return 0; 
}
```

##出力

```
which is %zu)ary01
zu) >= this->size() (which is %zu)vec1
```

#何がダメだったのか

まず、`std::string`型の変数を次のように`char`型で初期化することはコンパイルエラーとなるのでできません

```c++
// error!
char x = 'a';
std::string s_string_1 = x;
std::string s_string_2 = 'a';
```

しかし、何か他の文字列と組み合わせてあげるとコンパイルエラーを吐かなくなります。

```c++
// error?
char x = 'a';
std::string s_string_1 = x + "bcd";

std::cout << s_string_1 << std::endl;
```

コンパイルエラーは吐きませんが出力では空の文字列が出力されます。

```:出力

```

ここに
何か別の`std::string`型変数が**間**に入っているとコンパイルエラーも吐かず、出力も空文字列じゃなくなります。

```c++
char x = 'a';
std::string s_string_1 = "";
std::string s_string_2 = x + s_string_1 + "bcd";
std::string s_string_3 = 'a' + s_string_1 + "bcd";

std::cout << s_string_2 << std::endl;
std::cout << s_string_3 << std::endl;
```

```:出力
abcd
abcd

```

多分`char`に文字列リテラル繋げてるのが悪いんだなと思いつつ
ここから更に色々実験してみると確かに`char`に文字列リテラルを繋げるのが良くないみたいだと分かります。

<details><summary>実験</summary><div>

```c++:Exp.cpp
#include <iostream>
#include <string>
#include <array>
#include <vector>
int main()
{
    std::array<std::string, 5> ary = {
        "ary01", "ary02", "ary03", "ary04", "ary05"
    };
    std::vector<std::string> vec = {
        "vec1", "vec2", "vec3"
    };
    
    char x = 'x';
    std::string colon = ":";

    std::string s1 = 'x' + ":";
    std::string s2 = x + ":";
    std::string s3 = 'x' + colon;
    std::string s4 = x + colon;

    std::cout << '[' << "s1: " + s1 << "] [" << "s2: " + s2 << "] [" << "s3: " + s3 << "] [" << "s4: " + s4 << ']' <<std::endl;

    std::string test = "test";

    std::string s5 = x + ":" + test;
    std::string s6 = x + colon + test;
    std::string s7 = x + ":" + ary.at(0);
    std::string s8 = x + colon + ary.at(0);

    std::cout << '[' << "s5: " + s5 << "] [" << "s6: " + s6 << "] [" << "s7: " + s7 << "] [" << "s8: " + s8 << ']' <<std::endl;

    std::string s9  = ary.at(0).at(0) + ":" + test;
    std::string s10 = ary.at(0).at(0) + colon + test;
    std::string s11 = ary.at(0).at(0) + ":" + ary.at(0);
    std::string s12 = ary.at(0).at(0) + colon + ary.at(0);
    std::string s13 = vec.at(0).at(0) + ":" + vec.at(0);
    std::string s14 = vec.at(0).at(0) + colon + vec.at(0);

    std::cout << '[' << "s9: " + s9 << "] [" << "s10: " + s10 << "] [" << "s11: " + s11 << "] [" << "s12: " + s12 << ']' <<std::endl;
    std::cout << '[' << "s13: " + s13 << "] [" << "s14: " + s14 << ']' << std::endl;

    char y = 'a';
    std::string s_string_1 = "";
    std::string s_string_2 = y + s_string_1 + "bcd";
    std::string s_string_3 = 'a' + "bcd" + s_string_2;

    std::cout << s_string_2 << std::endl;
    std::cout << s_string_3 << std::endl;

    return 0; 
}
```

```:出力
[s1: is %zu) >= _Nm (which is %zu)] [s2: is %zu) >= _Nm (which is %zu)] [s3: x:] [s4:その結果
[s5: is %zu) >= _Nm (which is %zu)test] [s6: x:test] [s7: is %zu) >= _Nm (which is %zu)ary01] [s8: x:ary01]
[s9: test] [s10: a:test] [s11: ary01] [s12: a:ary01]
[s13: h is %zu) >= _Nm (which is %zu)vec1] [s14: v:vec1]
abcd
hich is %zu) >= this->size() (which is %zu)abcd
```

</div></details>


#あとがき
結論としては
`std::string`に`char`を含む文字列を代入、連結したいときは`char`に隣接する文字列の型を`std::string`にしなくてはならないということでした。
(演算の順番を考えたときに一番初めに`std::string`とつながるようにすればよい?)

ちなみに
`char` + `文字列リテラル`はコンパイル通りましたけど
`char` + `文字列リテラル` + `文字列リテラル`はコンパイル通りませんでした。
`char` + `文字列リテラル`で`const char*`となって`文字列リテラル`が`const char[]`
この二つが`+`に対して無効なオペランドであるとのエラーが出ます。

`const char*`と`const char[]`は`std::string`に型変換できるからそれを一緒に記述してやればコンパイルエラーが出なくなるのはわかるけど何故結果として空の文字列だとかエラーメッセージが格納されてるかは1ミリもわからないです。。。
`char + const char[]` => `const char*` => `std::string`
みたいな二回型変換が起こるのが良くないのかもしれません。