tại sao mã sau không biên dịch và khi tôi xóa Từ khóa rõ ràng trước hàm tạo trong lớp A, nó biên dịch?Ảnh hưởng của các nhà thầu "rõ ràng" trong quá trình phân giải quá tải
Sử dụng Visual Studio 2013:
enum E { e1_0, e1_1 };
template<typename T>
struct A
{
A() {}
explicit A(unsigned long) {}
A(T) {}
};
struct B
{
B() {}
B(E) {}
};
void F(B) {};
void F(A<short>) {};
void test()
{
F(e1_0);
}
Lỗi:
1>------ Build started: Project: exp_construct_test, Configuration: Debug Win32 ------
1> exp_construct_test.cpp
1>e:\exp_construct_test\exp_construct_test.cpp(23): error C2668: 'F' : ambiguous call to overloaded function
1> e:\exp_construct_test\exp_construct_test.cpp(19): could be 'void F(A<short>)'
1> e:\exp_construct_test\exp_construct_test.cpp(18): or 'void F(B)'
1> while trying to match the argument list '(E)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Edit: tôi tải kêu vang và biên soạn với kêu vang-cl mà báo cáo lỗi cho cả hai trường hợp. Vì vậy, như đã được chỉ ra trong bình luận, sự mơ hồ là giữa A<short>(short)
và B(E)
. Vì vậy, có lẽ có một lỗi trong VC + +, rằng khi tôi loại bỏ explicit
từ A(unsigned long)
, trình biên dịch bởi bất cứ ý định chọn B (E) thay vì để nâng cao một lỗi ambiguouity. Quay lại đầu trang | Bất cứ ai có thể xác nhận hành vi kêu vang như tuân thủ tiêu chuẩn, và VC + + như lỗi?
tôi thêm
void G(E) {};
void G(short) {};
và một lời kêu gọi G như thế này:
G(e1_0);
Mà không tăng bất kỳ lỗi. Tại sao ở đây G(E)
được đặt trước và trong trường hợp các ứng viên A<short>::A(short)
và B::B(E)
, chúng mơ hồ?
End Sửa
Cảm ơn --joja
Nếu tôi xóa 'tường minh', nó cũng không biên dịch, cũng không được. Các cuộc gọi mơ hồ không phải là 'A :: A' nhưng để 'F'. Lưu ý rằng 'A :: A (T)' không phải là 'tường minh', do đó cuộc gọi đến' F' là mơ hồ. Nếu bạn thêm * '' '' vào 'A :: A (T)', nó sẽ loại trừ chuyển đổi đó và mã sẽ biên dịch. – 5gon12eder
Từ khóa rõ ràng ở phía trước của một hàm tạo ngăn một đối tượng thuộc loại đó được khởi tạo ngầm với chỉ một tham số sẽ hoạt động như một đối số hàm tạo. Khi bạn xóa 'tường minh' khỏi hàm tạo của A, bạn có thể xây dựng A đơn giản bằng cách truyền 'void F (A)' một đoạn ngắn, đó là những gì F (e1_0) dường như đang làm –
Prismatic
@ 5gon12eder, trình biên dịch nào bạn đang sử dụng? Trong VS2013 nó biên dịch mà không có 'tường minh'. Tôi biết, rằng các cuộc gọi mơ hồ là 'F', nhưng nguyên nhân là việc chuyển đổi' e1_0' thành một loại mà quá tải của 'F' chấp nhận. Khi 'clear' được loại bỏ, trình biên dịch chọn' B (E) 'để thực hiện chuyển đổi và gọi' F (B) '. Tôi đã thêm 'rõ ràng' để chắc chắn, rằng tôi không ngầm sử dụng hàm tạo, mà là một trường hợp đặc biệt chỉ có hàm tạo trong mã thực của tôi. Theo ý kiến của tôi, việc sử dụng 'rõ ràng' thậm chí sẽ hướng dẫn trình biên dịch sử dụng chuyển đổi B (E) nhiều hơn và không xem xét một' enum E' thành 'unsigned long' promotion. – joja