Có một số cách để buộc các trình biên dịch C++ để thực hiện tra cứu tên cho một biểu tượng cho trong mẫu instantiation (và không phải trước đó)?
Có. Trước hết, tên phải phụ thuộc. Tên f
trong wrapper
khi được sử dụng làm f(t)
phụ thuộc vì t
phụ thuộc vào loại. [Temp.dep]/1:
Trong một biểu thức có dạng:
postfix thể hiện (
biểu-list opt)
nơi postfix thể hiện là một không đủ tiêu chuẩn-id, các không đủ tiêu chuẩn-id biểu thị một tên phụ thuộc nếu
- bất kỳ biểu thức trong biểu-list là một mở rộng gói (14.5.3),
- bất kỳ biểu thức nào trong danh sách biểu thức là cụm từ phụ thuộc vào loại (14.6.2.2), hoặc
- nếu không đủ tiêu chuẩn-id là một mẫu-id trong đó bất kỳ đối số mẫu phụ thuộc vào một số mẫu.
Vấn đề là tên tuyên bố sau khi mẫu đó, ví dụ: chỉ trong instantiation nhưng không phải là bối cảnh định nghĩa, chỉ có thể được tìm thấy bằng luận tên phụ thuộc tra cứu. f
quá tải của bạn chỉ mất loại cơ bản, nhưng những người không có không gian tên toàn cầu liên kết với chúng theo [basic.lookup.argdep]/2:
Nếu T
là một loại cơ bản, bộ liên quan của nó trong không gian tên và lớp học đều trống.
Do đó, bạn không bao giờ có thể tìm thấy f
nếu đối số có cùng loại với tham số. Một mẹo nhỏ có thể giúp:
template <typename T>
struct refwrap
{
T&& t;
refwrap(T&& t) : t(std::forward<T>(t)) {}
operator T&&() {return std::forward<T>(t);}
};
template <typename T>
auto make_refwrap(T&& t) -> refwrap<T> // making use of reference collapsing
{ return {std::forward<T>(t)}; } // inside refwrap to get forwarding
mẫu này, khi khai báo trong namespace toàn cục, sẽ gây ra ADL để xem xét nó. Viết lại wrapper
như sau:
template <class T>
auto wrapper(T t) -> decltype(f(make_refwrap(t)))
{
return f(make_refwrap(t));
}
Demo. Đây không phải là cách thích hợp để làm điều đó mặc dù, vì nó sẽ thất bại trong các kịch bản phức tạp hơn.
Tại sao bạn không sử dụng chuyên môn mẫu? – Chiel
@Chiel: Cảm ơn, ý tưởng tuyệt vời! Vì vậy, tôi sẽ thay thế 'f' bằng một mẫu lớp? Điều đó làm việc, nhưng tôi đã hy vọng cho một giải pháp mà sẽ không yêu cầu tôi thay đổi định nghĩa của 'f' (rất nhiều). Hay bạn có điều gì khác trong tâm trí? –
Bạn có thể sử dụng mặc định áp dụng cho hầu hết các trường hợp và chuyên môn khi được yêu cầu, xem câu trả lời của tôi. – Chiel