爺感:ドカンと代入したり戻したり
ジイサマ(=自分)の感覚だと、Cの代入演算子 = でセットできるのは単純な型だ、という先入観がある。s = "abc"; はstrcpy()やstrdup()とは違う。if (s == t) のように文字列を比較してもしょうがない、strcmp() 使え、ってことになる。
ところが、最近だと演算子オーバーロードが出来るので、デカくて複雑なデータでも、= でコピーして == で比較ができる。= がstcpy()のように使える、ってのがどうも馴染めない。
同じ感覚だと思うが、
std::string foo() { std::string s; // ... return s; }
も、一瞬ヒヤッとする。これもオブジェクト自体が戻るんで大丈夫なんだけど、「オブジェクト自体が戻る」ってのが馴染めない、慣れない。昔のコンパイラって、引数に載せるのも戻り値で返せるのも、intサイズだったかlongサイズだったか、ともかく整数レベルだったと思う。
要するに、爺感では、次のものは「整数サイズ」に限定されるのだ。
- 引数
- 戻り値
- = での代入
- == で比較できる。
最近は違うわけだよ。
#include <iostream> struct foo { int foo_1; long foo_2; foo() { foo_1 = 0; foo_2 = 0; } }; std::ostream& operator<<(std::ostream& os, const foo& x) { os<< "[" << x.foo_1 << ", " << x.foo_2 << "]"; return os; } foo make_foo() { foo x; return x; } foo inc_foo(foo x) { x.foo_1 += 1; x.foo_2 += 1; return x; } foo& inc_foo_ref(foo& x, int y = 1) { x.foo_1 += y; x.foo_2 += y; return x; } int main() { foo x1 = make_foo(); std::cout << "x1=" << x1 << std::endl << std::endl; foo x2 = inc_foo(x1); std::cout << "x2=" << x2 << std::endl; std::cout << "x1=" << x1 << std::endl << std::endl; foo& x3 = inc_foo_ref(x1, 2); std::cout << "x3=" << x3 << std::endl; std::cout << "x2=" << x2 << std::endl; std::cout << "x1=" << x1 << std::endl << std::endl; inc_foo_ref(x1, 3); std::cout << "x3=" << x3 << std::endl; std::cout << "x2=" << x2 << std::endl; std::cout << "x1=" << x1 << std::endl << std::endl; return 0; }
ウーム。