何らかの方法で引数を操作してから引数への参照を返すように関数をオーバーロードしたいのですが、引数が変更可能でない場合、引数のコピー代わりに。 年を重ねると、ここで私が思いついたことがあります。rvalue関数のオーバーロード
using namespace std;
string& foo(string &in)
{
in.insert(0, "hello ");
return in;
}
string foo(string &&in)
{
return move(foo(in));
}
string foo(const string& in)
{
return foo(string(in));
}
このコードは正しく動作するようですが、誰かがより良いやり方を考えることができるかどうか聞いてみたいと思います。もちろん、
string& foo(string &in)
{
in.insert(0, "hello ");
return in;
}
string foo(string in)
{
return move(foo(in));
}
:
int main(void)
{
string var = "world";
const string var2 = "const world";
cout << foo(var) << endl;
cout << var << endl;
cout << foo(var2) << endl;
cout << var2 << endl;
cout << foo(var + " and " + var2) << endl;
return 0;
}
正しい出力が
hello world
hello world
hello const world
const world
hello hello world and const world
である私はこれを行うことができれば、私はそれが少し滑らかな印象になります図:
は、ここでのテストプログラムですfoo
へのほとんどの関数呼び出しがあいまいであるため、機能しません。foo
自身!しかし、何とかコンパイラに最初のものに優先順位を付けるように指示できたら...
私が言ったように、コードが正しく動作します。私が気に入らない主なものは、繰り返しの余分なコードです。もし私がそのような機能を持っていたら、それはかなり混乱し、そのほとんどは非常に繰り返します。だから私の質問の2番目の部分:誰もが自動的に2番目と3番目のfoo
関数のコードを生成する方法を考えることができますか?例:
// implementation of magic_function_overload_generator
// ???
string& foo(string &in);
magic_function_overload_generator<foo>;
string& bar(string &in);
magic_function_overload_generator<bar>;
// etc
これは恐ろしい音です。関数に渡す型に応じて、戻り値*とパラメータ*の結果状態は完全に異なる場合があります。それは微妙なバグを求めているだけです。なぜあなたは、その場でオブジェクトを修正したいのか、明示的に別の関数を呼び出すことによってコピーを返すのかをユーザに決めるのはどうですか? – jalf
私は特に怖いとは思われませんが、あなたが正しいかもしれません。私が考えているのは、関数が可能な限り入力を変更するということです。それができない場合は...それはしませんが、それでも正しい戻り値を返します。 私はそれを使用するかもしれない種類のものは、 "punctuate"関数のようなものです。これは、途切れていない文字列を取り、それを修正します。結果をcoutに直接送るか、後でその文字列に対して他の操作をしたいかもしれません。だから時々あなたは一定の価値を渡すかもしれません、時には...よくあなたはそのアイデアを得ます。 – karadoc
しかし、私の指摘は、プログラマが望むものではなく、比較的微妙な意味の詳細(引数の型constかどうか、それはrvalueかどうか)に依存します。)これは、プログラマが明示的に「現在の場所でオブジェクトを修正するのではなく、コピーを返す」という決定をしなくても、時間の経過とともに容易に変更される可能性があります。私はあなたがしようとしていることを理解していますが、それはプログラマーが簡単に作ることができる決定であり、あなたのライブラリーを間違った推測にすることは潜在的に非常に悪い結果をもたらす可能性があります。 – jalf