Tại sao T(const bool)
được ưu tiên hơn T(const std::string&)
khi xây dựng t
?
""
thuộc loại char[1]
; điều này được chuyển đổi hoàn toàn thành char const*
thông qua chuyển đổi mảng-thành-con trỏ. Một con trỏ được chuyển đổi hoàn toàn thành bool
, với tất cả các con trỏ không null trở thành true
và tất cả các con trỏ null trở thành false
. Đây là cả hai chuyển đổi chuẩn "được tích hợp sẵn".
Chuyển đổi char const* -> std::string
là chuyển đổi do người dùng khai báo: nó sử dụng một hàm tạo chuyển đổi là std::string
có số char const*
.
Chuyển đổi tiêu chuẩn ("được tích hợp") được ưu tiên hơn chuyển đổi do người dùng khai báo trong quá trình phân giải quá tải, do đó nhà xây dựng lấy bool
là kết hợp tốt hơn so với số std::string
.
Còn bây giờ công việc duy nhất xung quanh tôi đã tìm thấy là thêm constructor khác
Đó có vẻ là một giải pháp hợp lý; chắc chắn là giải pháp đơn giản nhất cho kịch bản đơn giản mà bạn mô tả. Tuy nhiên, việc sử dụng bài tập của bạn cho *this
hơi vụng về; nó sẽ là tốt hơn hoặc để có cả hai nhà thầu đại biểu cho một số chức năng khởi tạo.
Ngoài ra, bạn có thể sử dụng một mẫu với enable_if
đối với bất kỳ nhà xây dựng mà bạn muốn không cho phép chuyển đổi:
template <typename U>
T(U, std::enable_if<std::is_same<U, bool>::value>::type* = 0) { }
constructor này sẽ chỉ có thể được gọi với một đối số bool
và không có gì khác. Bạn có thể tìm thấy enable_if
và is_same
trong Boost, C++ TR1 hoặc C++ 0x. Bạn cũng có thể sử dụng !is_pointer
, is_integral
hoặc một số kết hợp loại đặc điểm khác để cho phép đối với một số loại đối số khác chứ không phải char const*
.
Hoặc, như một giải pháp thay thế khác, bạn có thể tránh hoàn toàn bool
và sử dụng điều tra của riêng bạn với các điều tra viên tương ứng với true
và false
cho hàm tạo. Cho dù điều này có ý nghĩa hay không tùy thuộc vào trường hợp sử dụng của bạn.
Tuyên bố explicit T(const bool)
để tránh không giải quyết được vấn đề trên ... tại sao biểu mẫu T t("")
vẫn được phép và gọi T(const bool)
?
explicit
chỉ không cho phép chuyển đổi ẩn thành T
. T t("");
không có chuyển đổi nào đối với T
; nó trực tiếp khởi tạo đối tượng t
bằng cách xây dựng nó với đối số ""
được truyền cho bất kỳ hàm tạo nào phù hợp nhất.
cảm ơn nhiều giải pháp với Mẫu – pipex
'enable_if' sẽ kết thúc bằng' ... :: type * = 0'. – UncleBens
@UncleBens: Rất cám ơn. Đã sửa. –