2012-04-05 34 views
12

Nếu bạn quá tải một chức năng và sau đó gọi nó với một lập luận cho rằng hoàn toàn phù hợp với một trong những quá tảiQuy tắc chuyển đổi ngầm của đối số mẫu

int f(int){return 3;} 
int f(bool){return 4;} 
...  //inside main() 
f(1);  //Calls f(int) 

trình biên dịch chỉ đơn giản là chọn này (hoàn hảo) phù hợp trước khi thực hiện bất kỳ chuyển đổi ngầm . Tuy nhiên tôi đã cố gắng để quá tải một hàm template như trong

template <bool veracity> 
int f(){return 1;} 

template <int amount> 
int f(){return 2;} 

...  //inside main() 
f<1>(); 

nhưng trình biên dịch tiếp tục complainning về cuộc gọi mơ hồ đến f quá tải(), trong đó nêu nó có thể là một trong hai f<true>() hay f<1>(). Không nên trình biên dịch chỉ chọn kết hợp hoàn hảo, thay vì cố gắng chuyển đổi thành đúng?

Tôi đã ấn tượng rằng chuyển đổi tiềm ẩn cho đối số mẫu thực sự hạn chế hơn chuyển đổi ngầm định đối số hàm. Có cách nào để giải quyết vấn đề này không?

Trả lời

8

Đối số bạn đang cung cấp không phải là một loại, đó là một giá trị, vì vậy các quy tắc có một chút khác biệt - bạn cần áp dụng quy tắc cho đối số không phải loại. Đối với các đối số không loại, cho phép chuyển đổi ngầm định. §14.3.2/5:

Các chuyển đổi sau được thực hiện trên mỗi biểu thức được sử dụng làm đối số mẫu không phải kiểu. Nếu một đối số mẫu không kiểu không thể được chuyển đổi thành kiểu của tham số mẫu tương ứng thì chương trình đó không đúng định dạng.

- Đối với một tham số mẫu không kiểu của loại tích phân hoặc liệt kê, các chuyển đổi được phép trong biểu thức hằng số được chuyển đổi (5.19) được áp dụng.

Trong C++ 03, từ ngữ là nhẹ khác nhau, nhưng hiệu quả về cơ bản giống hệt nhau (cũng §14.3.2/5):

- cho một tổ chức phi kiểu mẫu tham số của tích phân hoặc kiểu liệt kê, khuyến mại tích phân (4.5) và chuyển đổi tích phân (4.7) được áp dụng.

Dù bằng cách nào, vì 1 là cả một int và ngầm chuyển đổi thành một bool, cuộc gọi của bạn là mơ hồ.

+0

tôi nhìn thấy. Bạn có biết nếu có một lý do cụ thể tại sao các quy tắc như thế này? Tôi có nghĩa là, có một số khó khăn kỹ thuật hoặc một cái gì đó mà sẽ làm cho nó imnpracticable cho trình biên dịch để áp dụng "chính xác phù hợp với đầu tiên/ngầm-chuyển đổi-thứ hai" logic (được sử dụng trong các đối số chức năng) cho các đối số mẫu? – Malabarba

+0

Không, tôi không biết chắc chắn. Đoán của tôi sẽ là nó chủ yếu là vì các quy tắc đã được phức tạp, và thêm một bộ quy tắc cho "xếp hạng" như nó không cho quá tải sẽ làm cho họ thậm chí nhiều hơn như vậy. Tôi không chắc chắn, nhưng tôi đoán là do tương tác với các quy tắc khác cho các mẫu, các quy tắc xếp hạng sẽ kết thúc ít nhất một chút khác với các quy tắc cho quá tải, vì vậy nó sẽ không chỉ là vấn đề nói "các chức năng của ứng cử viên sẽ tạo thành một bộ quá tải được giải quyết theo §13.3." –

+0

Làm cho tinh thần.Cảm ơn. =) – Malabarba

5

Vì đây không phải là lỗi trình biên dịch mà là tính năng ngôn ngữ (xem this answer), bạn phải tìm một công việc xung quanh.

Hoặc là bạn phải đổi tên các chức năng của bạn hoặc bạn có thể sử dụng hack này:

template <typename T> struct F; 

template<> struct F<bool> { 
    template <bool veracity> 
    static int f(){return 1;} 
}; 

template<> struct F<int> { 
    template <int amount> 
    static int f(){return 2;} 
}; 

template <typename T, T value> 
int f() { return F<T>::template f<value>(); } 

// inside main(): 
std::cout << f<int, 2>() << '\n'; // prints 2 
std::cout << f<bool, 2>() << '\n'; // prints 1 
Các vấn đề liên quan