Tôi muốn viết một hàm foo
rằng nên gọi operator()
của tham số của nó, như minh họa trong (bị hỏng) mã bên dưới:Chuyển tiếp const-ness của thông số mẫu, tôi có nên sử dụng tham chiếu chuyển tiếp không?
template <typename T> void foo(const T& x){
x();
}
struct MyFunctor{
int data;
void operator()(){
/* stuff that might modify the data */
}
};
int main()
{
foo(MyFunctor{});
}
Rõ ràng mã không hoạt động, vì operator()
là phi const
, nhưng foo()
yêu cầu tham số của nó là const
.
Là chức năng mẫu, foo()
phải hoạt động với cả hai đối tượng const
và không phải là const
và không phải là cầu nối về đối số của nó.
Nếu tôi thay đổi foo()
bằng cách loại bỏ các const
như sau:
template <typename T> void foo(T& x) { /* ... */ }
... nó cũng sẽ không làm việc vì bạn không thể chuyển đổi một tài liệu tham khảo rvalue đến một const
tài liệu tham khảo không vế trái, vì vậy Không thể gọi số foo(MyFunctor{})
.
Thay đổi foo()
đến một tham chiếu giao nhận giải quyết tất cả các vấn đề:
template <typename T> void foo(T&& x) { /* ... */ }
Nhưng đây là "đúng" cách? Tham chiếu chuyển tiếp không nên chỉ được sử dụng với std::forward()
(tức là thông số không được xúc động ngoài việc chuyển tiếp tham chiếu đến chức năng khác)?
Bạn có thể muốn đọc [Tham khảo chung trong C++ 11 — Scott Meyers] (https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers). Nó chứa một số giải thích sâu về việc sử dụng 'T && x'. – VTT
Điều này là hoàn toàn tốt IMO –
Tôi vinh dự có những người có danh tiếng sáu chữ số trả lời câu hỏi của tôi! – Bernard