Hãy xem xét một lớp họcMỘT
, làm cách nào để viết một hàm với
Các mẫu có hành vi tương tự
A& xinh đẹp(A&x)
{
/*làm cho x đẹp*/
trả lại x;
}
Một người đẹp(A&& x)
{
/*làm cho x đẹp*/
trả lại x;
}
Biết những gì tôi muốn:
Sửa đổi các tham số theo cách tương tự (x
), bất kể đối số là tham chiếu giá trị hay tham chiếu giá trị (trên thực tế, cả hai phần /*làm cho x đẹp*/
giống hệt nhau) và do đó có một chức năng duy nhất;
Tránh sự trùng lặp không cần thiết;
Khả năng sử dụng các hàm để sửa đổi các biến;
Khả năng thực hiện các lệnh gọi hàm "đường ống" bất kể đối số là giá trị hay giá trị.
Như ví dụ về 3. và 4., hãy xem xét trường hợp sử dụng sau:
void read_A(const A& x) { /* ... */ }
void take_A(A&& x) { /* ... */ }
Một x();
read_A(đẹp(x));
take_A(đẹp(A()));
Ý tưởng của tôi là tận dụng việc chuyển tiếp các tham chiếu đồng thời giới hạn các đối số được phép MỘT
trích dẫn. Nhưng còn kiểu trả về thì sao?
mẫu
std::enable_if_t<>::value>
/*???*/ khá(T&& x)
{
/*làm cho x đẹp*/
trả về x; //?
}
Tại sao không chỉ viết
#include
mẫu
T somefunc(T&& a) {
/* làm gì đó với dấu */
std::cout << __PRETTY_FUNCTION__ << '\n';
trả về std::forward(a);
}
int main(int argc, char* argv[]) {
int a = 5;
somefunc(a);
một số chức năng (5);
trả về 0;
}
sẽ trở lại
T somefunc(T &&) [T = int &]
T somefunc(T &&) [T = int]
Như bạn có thể thấy, hàm này có chữ ký mà bạn muốn. Trong cuộc gọi đầu tiên,T
Lấy int &
,Vì vậy,int &
giá trị trả về. Trong cái thứ hai bạn có T = int = int &&
, đó cũng là điều bạn muốn.
biên tập. Nhân tiện, ý tưởng ban đầu của bạn là áp dụng std::is_same
vô hiệu hóa MỘT
Độ phân giải quá tải đối với các loại khác dường như cũng sai dựa trêncppreference ,
Nếu như T
Và bạn
đặt tên cùng loại với cùng đặc tính khả biến const, cung cấp giá trị hằng số thành viên bằng ĐÚNG VẬY
Nếu không thì giá trị là . SAI
.
Vì vậy, bạn có thể muốn sử dụng một cái gì đó nhưphân hủy
một cái gì đó, hoặc ít nhấtxóa_cv
Vàxóa_reference
kết hợp để áp dụng logic bạn muốn. Dưới đây là phiên bản sửa đổi của mã ở trên hiện bao gồm trình khởi động phân tích cú pháp quá tải.
#include
#include
mẫu T somefunc(T &&a) {
/* làm gì đó với dấu */
std::cout << __PRETTY_FUNCTION__ << '\n';
trả về std::forward(a);
}
mẫu
std::is_same::type, float>::value,
int>::loại = 0>
T onlyfloat_core(T &&a) {
/* làm gì đó với dấu */
std::cout << __PRETTY_FUNCTION__ << '\n';
trả về std::forward(a);
}
mẫu
tên kiểu std::enable_if<>::value, int>::type = 0>
T onlyfloat_wrong(T &&a) {
/* làm gì đó với dấu */
std::cout << __PRETTY_FUNCTION__ << '\n';
trả về std::forward(a);
}
int main(int argc, char *argv[]) {
int a = 5;
const float b = 5;
somefunc(a);
một số chức năng (5);
onlyfloat_core(b);
// onlyfloat_wrong(b);
trả về 0;
}
Tôi là một lập trình viên xuất sắc, rất giỏi!