Gần đây tôi đã đọc ở đâu đó (không thể nhớ vị trí) về cách sử dụng dấu ngoặc để cho phép nhiều chuyển đổi do người dùng xác định, nhưng dường như có sự khác biệt giữa chuyển đổi theo hàm tạo và chuyển đổi theo phương pháp chuyển đổi Tôi không hiểu.Chuyển đổi ngầm C++ với bộ khởi tạo ngoặc đơn
xem xét:
#include <string>
using ::std::string;
struct C {
C() {}
};
struct A {
A(const string& s) {} // Make std::string convertible to A.
operator C() const { return C(); } // Makes A convertible to C.
};
struct B {
B() {}
B(const A& a) {} // Makes A convertible to B.
};
int main() {
B b;
C c;
// This works.
// Conversion chain (all thru ctors): char* -> string -> A -> B
b = {{"char *"}};
// These two attempts to make the final conversion through A's
// conversion method yield compiler errors.
c = {{"char *"}};
c = {{{"char *"}}};
// On the other hand, this does work (not surprisingly).
c = A{"char *"};
}
Bây giờ, tôi có thể bị hiểu sai những gì trình biên dịch được thực hiện, nhưng (dựa trên các thử nghiệm trên và bổ sung) có vẻ như với tôi rằng nó không xem xét chuyển đổi bằng cách chuyển đổi-method. Đọc qua các phần 4 và 13.3.3.1 của tiêu chuẩn, tuy nhiên, tôi đã không thể tìm thấy một đầu mối tại sao lại như vậy. Giải thích là gì?
Cập nhật
Đây là một hiện tượng thú vị, tôi muốn giải thích. Nếu tôi thêm
struct D {
void operator<<(const B& b) {}
};
và trong main
:
D d;
d << {{ "char *" }};
tôi nhận được một lỗi, nhưng nếu thay vào đó tôi viết d.operator<<({{ "char *" }});
nó hoạt động tốt.
Cập nhật 2
Hình như mục 8.5.4 trong tiêu chuẩn có thể giữ một số câu trả lời. Tôi sẽ báo cáo những phát hiện của tôi.
Một khởi tạo sử dụng các nhà xây dựng và sẽ không sử dụng toán tử chuyển đổi của một loại trung gian. Hai ví dụ không làm việc thất bại vì ngầm xây dựng một 'A' để sử dụng toán tử' 'của nó đi ngược lại với điều này. – Peter
Liên quan: http://stackoverflow.com/questions/35790664/why-cant-i-implicitly-construct-an-object-given-a-suitable-constructor-when-pas/35790867#35790867 –
Peter, những gì tôi ' m cố gắng hiểu là những gì các quy tắc là chính xác. Nếu tôi viết 'c = A {...' hoặc 'c = {A {...' nó hoạt động tốt thông qua phương thức chuyển đổi. Tại sao nó quyết định chỉ sử dụng ctors nếu tôi thả 'A'? – Ari