返される変数が関数のスコープ外になった場合の C++ の戻り値の最適化についてはかなりよく理解していますが、メンバー変数を返す場合はどうでしょうか。次のコードを検討してください。
#include <iostream>
#include <string>
class NamedObject {
public:
NamedObject(const char* name) : _name(name) {}
std::string name() const {return _name;}
private:
std::string _name;
};
int main(int argc, char** argv) {
NamedObject obj("name");
std::cout << "name length before clear: " << obj.name().length() << std::endl;
obj.name().clear();
std::cout << "name length after clear: " << obj.name().length() << std::endl;
return 0;
}
どの出力:
name length before clear: 4
name length after clear: 4
明らかに、 はobj.name().clear()
一時コピーに作用しますが、 への呼び出しはobj.name.length()
どうですか? std::string::length()
メンバー関数であるconst
ため、文字列の状態を変更しないことが保証されています。したがって、コンパイラがメンバー変数をコピーせず、const メンバー関数の呼び出しに直接使用することを許可する必要があるのは妥当と思われます。最新の C++ コンパイラはこの最適化を行いますか? 作ってはいけない、または作れない理由はありますか?
編集:
明確にするために、標準の戻り値の最適化がここで機能するかどうかを尋ねているわけではありません。最初に質問した時点でなぜそうでないのか理解しました。返される値が関数の範囲外に出ないという理由だけで、RVO が通常定義されている方法はここでは機能しません。
私が求めているのは、呼び出し時にコンパイラーが呼び出しに副作用がないと判断できる場合、コピーをスキップできるかどうかです。つまり、あたかも
obj.name().length()
そうだった
obj._name.length()