này không có gì để làm với các mẫu, bạn sẽ có được kết quả tương tự nếu T
chỉ là một typedef cho std::string&
chứ không phải là một mẫu tham số suy luận:
#include <string>
typedef std::string& T;
T Foo(int & i)
{
return T(i);
}
int main()
{
int a = 1;
std::string & s = Foo(a);
}
câu trả lời Dietmar đã làm tôi nhận ra điều này có thể được tiếp tục đơn giản hóa để:
#include <string>
typedef std::string& T;
int main()
{
int a = 1;
std::string & s = T(a);
}
nơi T(a)
cũng giống như các diễn viên (T)a
tức (std::string&)a
mà (theo các quy tắc của 5.4 [expr.cast]) sẽ làm một const_cast
nếu đó là hợp lệ (mà nó không phải là) hoặc một static_cast
nếu đó là hợp lệ (không phải là) hoặc static_cast
nếu có giá trị là const_cast
nếu đó là hợp lệ (không phải là) hoặc reinterpret_cast
nếu hợp lệ (là) hoặc reinterpret_cast
nếu số đó hợp lệ, nếu không thì biểu hiện không đúng định dạng.
Vì vậy, khi Dietmar nói, nó giống như làm một reinterpret_cast
, tức là
std::string & s = reinterpret_cast<std::string&>(a);
tôi thấy nó khá ngạc nhiên rằng mã gốc biên dịch, nhưng vì nó cũng giống như dòng trên, nó cho phép để biên dịch . Sử dụng kết quả của diễn viên là hành vi không xác định mặc dù.
Để tránh sự ngạc nhiên khi T(a)
tương đương với dàn diễn viên, hãy sử dụng cú pháp khởi tạo đồng nhất C++ 11 mới, T{a}
, luôn là khởi tạo chứ không phải biểu thức truyền.
Câu hỏi hay, điều tra và trả lời nó cho tôi thấy một hình ảnh xác thực mới mà trước đây tôi chưa từng biết, nhờ JaredC và Dietmar cho phần kiến thức mới!
Nguồn
2012-12-17 00:58:32
Không gây sốc kinh khủng cho chuyên môn của bạn không được gọi nếu bạn đang gọi 'Foo(a);' và mong muốn chuyên môn hóa 'Foo () 'sẽ được kích hoạt. –
WhozCraig
@WhozCraig Tôi đồng ý, tôi đã tuyệt vọng vì nó không có ý nghĩa. – JaredC
Nó, tất nhiên, cháy, nếu bạn trực tiếp gọi 'Foo() ', nhưng đó không thực sự là những gì bạn đang tìm kiếm, không có nghi ngờ. –
WhozCraig