Tại sao nó gọi hàm tạo mặc định?


80
struct X
{
    X()    { std::cout << "X()\n";    }
    X(int) { std::cout << "X(int)\n"; }
};

const int answer = 42;

int main()
{
    X(answer);
}

Tôi đã mong đợi cái này sẽ in

  • X(int), bởi vì X(answer);có thể được hiểu là diễn từ intđến X, hoặc
  • không có gì cả, vì X(answer);có thể được hiểu là khai báo của một biến.

Tuy nhiên, nó in raX() và tôi không biết tại sao X(answer);lại gọi hàm tạo mặc định.

ĐIỂM THƯỞNG: Tôi sẽ phải thay đổi gì để có được khai báo tạm thời thay vì khai báo biến?


1
Câu trả lời X ((int)); tuy nhiên tạo ra kết quả chính xác.
Inisheer

2
@JTA Và cuối cùng, X(int(answer));không in bất cứ điều gì, bởi vì đó là một khai báo hàm :)
fredoverflow

1
không có gì cả, vì X (đáp án); có thể được hiểu là khai báo của một biến. Khai báo đó cũng sẽ là một định nghĩa, và nó kích hoạt việc thực thi hàm tạo mặc định ... điều này có nghĩa là bạn đã trả lời câu hỏi của chính mình.
David Rodríguez - dribeas

6
@ David double(expresso);có bạn đi, tuyên bố chỉ cho bạn;)
fredoverflow

2
@FredOverflow: Tôi phải cần một định nghĩa để sử dụng nó, bởi vì tôi cảm thấy không có tác dụng ...
David Rodríguez - dribeas

Câu trả lời:


73

không có gì cả, vì X (đáp án); có thể được hiểu là khai báo của một biến.

Câu trả lời của bạn được ẩn trong đây. Nếu bạn khai báo một biến, bạn gọi ctor mặc định của nó (nếu không phải POD và tất cả những thứ đó).

Về bản chỉnh sửa của bạn: Để có được tạm thời, bạn có một số tùy chọn:


4
Các static_cast<X>(answer)cảm nhận được "nhất C ++" câu trả lời - nó thậm chí còn khuyến cáo của một tuổi tài liệu GCC như một cách để buộc một rvalue.
Kerrek SB

Bộ khởi tạo dấu ngoặc nhọn cũng có thể tạo ra một bản sao phải không?
rubenvb

@rubenvb: Tại sao lại như vậy? Đó chỉ là một cách nói mới lạ mắt X(answer)và đảm bảo một cuộc gọi ctor.
Xeo

@Xeo: vì cú pháp bộ khởi tạo dấu ngoặc nhọn nhận các đối số của nó theo giá trị? (<- lưu ý các dấu hỏi)
rubenvb

4
@KerrekSB Nhưng chắc chắn chỉ trước C ++ 11, không? Bây giờ, câu trả lời chính tắc sẽ là X{answer}.
Konrad Rudolph

66

Dấu ngoặc đơn là tùy chọn. Những gì bạn đã nói giống hệt nhau X answer;, và đó là một tuyên bố khai báo.


9

Nếu bạn muốn khai báo một biến kiểu X, bạn nên làm theo cách sau:

X y(answer);

1
Anh ta không hỏi làm thế nào để gọi nó là X(int)ctor.
Xeo

Ừ nhưng tôi có một cảm giác nhỏ mà nó là điều ông ment làm :)
huysentruitw

6
@WouterH: Thực ra, biết Fred, điều đó khó xảy ra. Anh ấy là một trong những người thích khám phá những góc tối của Tiêu chuẩn C ++ và thử và hiểu nó. Trong một game nhập vai chắc chắn ông sẽ bị mất tất cả các điểm tỉnh táo của ông đã;)
Matthieu M.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.