我想重载一个函数,以便它以某种方式操作它的参数,然后返回参数的引用 - 但是如果参数不可变,那么它应该返回一个操纵的副本的参数代替。 经过一段时间的搞乱之后,这里就是我想到的。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));
}
此代码似乎能正常工作,但我很想听听有没有人能想到更好的方法来做到这一点。
这是一个测试程序:
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
我想这将是稍微整洁,如果我能做到这一点:
string& foo(string &in)
{
in.insert(0, "hello ");
return in;
}
string foo(string in)
{
return move(foo(in));
}
当然,这不起作用,因为大多数对foo
的函数调用都是不明确的 - 包括01中的调用本身!但如果我能以某种方式告诉编译器优先考虑第一个...
正如我所说的,我发布的代码工作正常。我不喜欢它的主要原因是重复的额外代码。如果我有一堆这样的功能,它会变得相当混乱,而且大部分都是非常重复的。作为我的问题的第二部分:任何人都可以想出一种方法来自动生成第二个和第三个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 2011-06-16 08:05:09
对我来说这似乎并不特别可怕,但也许你是对的。我想到的方式是该功能在输入时会改变输入;但如果它不能......那么它不会,但它仍然会给出正确的返回值。 我可能会使用它的一种东西就像是一个“标点符号”函数,它使用了一个不好打断的字符串并对其进行修复。您可能希望将结果直接发送到cout,或者您可能想在之后对字符串执行一些其他操作。所以有时你可能会传递不变的价值观,有时候......你明白了。 – karadoc 2011-06-16 08:26:07
但我的观点是,无论是其中一个还是另一个发生都不取决于程序员想要什么,而是取决于某些相对微妙的语义细节(参数类型是否为const?是否是右值?),如果程序员没有明确地做出“现在我想返回一个副本,而不是修改对象”的决定,它可能很容易随时间而改变。我明白你想要做什么,但这是程序员可以轻易做出的决定,以及在哪里让你的图书馆做出错误的猜测可能会有非常糟糕的后果。 – jalf 2011-06-16 08:32:35