Tôi muốn quá tải một hàm để nó thao tác đối số của nó theo một cách nào đó và sau đó trả về tham chiếu đến đối số - nhưng nếu đối số không thể thay đổi được, thì nó sẽ trả về thao tác sao chép của đối số thay thế. Sau khi rối tung xung quanh với nó cho các lứa tuổi, đây là những gì tôi đã đưa ra.Quá tải hàm 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));
}
Mã này có vẻ hoạt động chính xác nhưng tôi muốn biết liệu có ai có thể nghĩ cách tốt hơn để làm điều đó không.
Dưới đây là một chương trình thử nghiệm:
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;
}
Kết quả đúng là
hello world
hello world
hello const world
const world
hello hello world and const world
tôi con số đó sẽ là hơi gọn gàng nếu tôi có thể làm điều này:
string& foo(string &in)
{
in.insert(0, "hello ");
return in;
}
string foo(string in)
{
return move(foo(in));
}
Tất nhiên, không hoạt động vì hầu hết các cuộc gọi hàm đến foo
sẽ không rõ ràng - bao gồm cả cuộc gọi trong foo
! Nhưng nếu tôi bằng cách nào đó có thể yêu cầu trình biên dịch ưu tiên cho trình biên dịch đầu tiên ...
Như tôi đã nói, mã tôi đã đăng hoạt động chính xác. Điều chính tôi không thích về nó là mã phụ lặp đi lặp lại. Nếu tôi có một loạt các chức năng như thế thì nó sẽ trở thành một mớ hỗn độn, và hầu hết nó sẽ rất lặp đi lặp lại. Vì vậy, như là một phần thứ hai cho câu hỏi của tôi: bất cứ ai có thể nghĩ ra một cách để tự động tạo mã cho các chức năng thứ hai và thứ ba foo
? ví dụ:
// 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
Điều này nghe có vẻ đáng sợ. Tùy thuộc vào loại tôi chuyển tới hàm, trạng thái kết quả của giá trị trả về * và tham số * có thể hoàn toàn khác. Đó chỉ là yêu cầu cho các lỗi tinh tế. Tại sao không cho phép người dùng quyết định liệu họ có muốn sửa đổi đối tượng tại chỗ hay trả lại một bản sao bằng cách gọi một cách rõ ràng các chức năng khác nhau không? – jalf
Nó không có vẻ đặc biệt đáng sợ với tôi, nhưng có thể bạn đã đúng. Cách tôi nghĩ về nó là chức năng thay đổi đầu vào bất cứ khi nào nó có thể; nhưng nếu nó không thể ... sau đó nó không, nhưng nó vẫn mang lại giá trị trả về đúng. Loại điều tôi có thể sử dụng nó là một cái gì đó giống như chức năng "Dấu chấm câu", một chuỗi có dấu chấm câu kém và sửa lỗi. Bạn có thể muốn gửi kết quả trực tiếp tới cout, hoặc bạn có thể muốn thực hiện một số thao tác khác trên chuỗi sau đó. Vì vậy, đôi khi bạn có thể vượt qua các giá trị không đổi, và đôi khi ... bạn cũng có được ý tưởng. – karadoc
nhưng quan điểm của tôi là dù hoặc một hay khác xảy ra phụ thuộc vào những gì lập trình viên muốn, nhưng trên một số chi tiết ngữ nghĩa tương đối tinh tế (là loại đối số const hay không? Có phải là một giá trị hay không?), có thể dễ dàng thay đổi theo thời gian mà không có lập trình viên đưa ra quyết định rằng "bây giờ tôi muốn trả lại một bản sao, thay vì sửa đổi đối tượng tại chỗ". Tôi hiểu những gì bạn đang cố gắng làm, nhưng đó là một quyết định mà người lập trình có thể dễ dàng thực hiện và nơi thư viện của bạn đưa ra dự đoán sai có thể có hậu quả rất xấu. – jalf