2012-06-25 30 views
5

Với hai ký hiệu hàm dựng sau, bạn có thể xây dựng Couple với Couple("George", "Nora") không? Trình biên dịch của tôi phàn nàn với lỗi được hiển thị bên dưới. Nếu tôi gọi nó là Couple(std::string("George"), std::string("Nora")) thì nó sẽ biên dịch OK. Tôi đoán có một vấn đề với việc đúc tiềm ẩn mà tôi ngạc nhiên khi tôi mặc dù char * để chuỗi sẽ được sử dụng tốt.Có hợp lệ để có hai phôi tiềm ẩn trong việc xây dựng một đối tượng trong C++ không?

class Person 
{ 
    public: 
     Person(const std::string& name); 
}; 

class Couple 
{ 
    public: 
     Coordinate(const Person& p1, const Person& p2, const Optional<Person>& = Optional<Person>()); 
}; 

TestCouple.cpp:69: error: no matching function for call to `Couple::Couple(const char[7], const char[5])' 
TestCouple.h:24: note: candidates are: Couple::Couple(const Person&, const Person&, const Optional<fox::Person>&) 
+0

Tôi không thấy vấn đề, nó sẽ hoạt động. Bạn nên đăng bài kiểm tra tối thiểu đầy đủ. – Klaim

+2

Có phải 'Coordinate' là lỗi đánh máy không? Có nên không phải là 'Cặp đôi' thay thế không? – Nawaz

+1

Không có điều gì như một "diễn viên tiềm ẩn" trong C++. Casts là yêu cầu rõ ràng cho việc chuyển đổi, sử dụng cú pháp cast đặc biệt. Những gì bạn đang sau là chuyển đổi tiềm ẩn. – PlasmaHH

Trả lời

12

Thật vậy, một chuỗi chuyển đổi không thể chứa nhiều hơn một user- ngầm chuyển đổi được xác định; tiêu chuẩn quy định điều này trong C++ 11 12.3/4:

Tối đa một chuyển đổi do người dùng xác định (hàm tạo hoặc hàm chuyển đổi) được áp dụng ngầm định cho một giá trị duy nhất.

Trong trường hợp của bạn, hai sẽ được yêu cầu (char const[] để std::string-Person), và chuyển đổi để ngầm là không thể.

6

Bạn là chính xác rằng có một vấn đề với chuyển đổi ngầm. Nó sẽ chỉ thực hiện một chuyển đổi tiềm ẩn cho một giá trị, do đó bạn có thể thực hiện hoặc Couple(std::string("a"), std::string("b")) hoặc Couple(Person("a"), Person("b")), ví dụ, nhưng Couple("a", "b") sẽ yêu cầu trình biên dịch đưa vào hai chuyển đổi tiềm ẩn cho mỗi giá trị. Điều này không được phép theo tiêu chuẩn, bởi vì nó sẽ gây ra mã có thể khó hiểu một cách chính xác và tốn kém tính toán để biên dịch.

1

Chuyển đổi ngầm ẩn được cho phép. Nếu A ngầm có thể chuyển đổi thành BB ngầm có thể chuyển đổi thành C, sau đó nó không có nghĩa là A ngầm có thể chuyển đổi thành C.

//given three objects as 
A a; 
B b' 
C c; 

//premises 
b = a; //a can convert into b (implicitly) 
c = b; //b can convert into c (implicitly) 

//then it does not follow this 
c = a; //a CANNOT convert into c (implicitly) 

//you need to write this at least 
c = static_cast<B>(a); //ok 
+0

"_điều đó không có nghĩa là A có thể chuyển đổi thành C._" chính xác. Nitpick: nói rằng "' b = a' là hợp lệ "không tương đương với việc nói" A có thể chuyển thành B ". – curiousguy

+0

@curiousguy: Giải thích những gì bạn đang nói. Tại sao 'b = a' là hợp lệ ở nơi đầu tiên ở đây? – Nawaz

+0

Giả sử B là một loại lớp, 'b = a' là độ phân giải quá tải _iff_ hợp lệ có thể tìm thấy một kết quả phù hợp nhất cho' b.operator = (a) '. Bạn cũng có thể viết 'foo (a, b)', cho quá tải thích hợp của 'foo'. – curiousguy

Các vấn đề liên quan