C++ có ADL (Truy vấn phụ thuộc đối số), như tên của nó mô tả, ngữ cảnh (không gian tên) của hàm có thể được ngụ ý từ ngữ cảnh (không gian tên) của (bất kỳ) đối số nào.Giải pháp cho sự nghịch đảo của Tra cứu phụ thuộc đối số?
fun(a); // if the type of a is in namespace ns deduce ns::f if available
Câu hỏi của tôi là liệu kỹ thuật ngược lại có thể thực hiện được không? Ngược lại, ý tôi là nếu ngữ cảnh (không gian tên) có thể được suy ra từ ngữ cảnh của hàm được gọi. Một số loại "Chức năng phụ thuộc tra cứu" (FDL). Mã giả:
ns::fun(a); // deduce ns::a if available
Tôi không thể tìm ra cách để làm điều đó. Giới hạn này đặc biệt gây phiền toái cho enum
s được sử dụng để mã hóa các tùy chọn chức năng. Tôi muốn biết nếu có một kỹ thuật để mô phỏng tính năng này (C++ 11 sẽ là ok quá). Mã giả:
ns::fun(Saturday, Tuesday); // Saturday/Tuesday are enum values in namespace ns;
Đặc biệt nếu có giải pháp thay thế cho enum
s.
Mã này minh họa vấn đề này:
namespace longname{
class A{};
void fun(A const& a){}
A global_a;
enum Days { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday};
void gun(Days d1, Days d2){}
}
int main(){
longname::A a;
fun(a); // cool, longname::fun(a) not necessary, fun is deduced from context
longname::fun(global_a); // error, not cool, global_a context not deduced,
// must use then longname::fun(longname::global_a)
longname::gun(Saturday, Tuesday); // error, particularly not cool, the Saturday is not deduced from context
// must use then longname::gun(longname::Saturday, longname::Tuesday)
// or at best gun(longname::Saturday, longname::Tuesday)
}
EDIT: @jrok gợi ý một cách giải quyết dựa trên định nghĩa namespace lồng nhau. Đối với trường hợp enum
, tôi nhận được mã này. Mà vẫn có một số tiếng ồn (có thực sự không có "phụ thuộc" tra cứu ở tất cả) nhưng nó là một sự cải tiến.
namespace longname{
namespace days{
enum _ { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday};
}
void gun(days::_ d1, days::_ d2){}
}
int main(){
using namespace longname::days; // some noise still here
longname::gun(Saturday, Tuesday);
}
Tôi không sử dụng enum class
vì sau đó Saturday
, Sunday
, vv không thể Brough trực tiếp trong phạm vi (trên thực tế using longname::days::_
sẽ cung cấp cho tôi một lỗi biên dịch)
ok, sau khi gửi câu hỏi của tôi: Tôi có một câu hỏi liên quan trên bảng bên phải http://stackoverflow.com/questions/14163667/why-does-c11-not-support-name-lookup-like- này? rq = 1. Có thể cho rằng, sự khác biệt ở đây là tôi không đặt câu hỏi về ngôn ngữ nhưng tôi đang tìm kiếm một kỹ thuật workaround. – alfC
Cách giải quyết: Đặt enum vào một không gian tên lồng nhau và nói 'using namespace longname :: lồng nhau;' trong 'main'. – jrok
@jrok, tuyệt vời, điều đó gần hơn với giải pháp (tôi đã thêm đề xuất của bạn vào câu hỏi). – alfC