2017-03-23 13 views
7

Trong khi tôi đã được đọc về chuyển đổi kiểu dữ liệu, tôi thấy ví dụ này:Trong C++, chúng ta có thể sử dụng {} để đúc kiểu C?

void intval() 
{ 
    for (char c; cin >> c;) 
    cout << "the value of '" << c << "' is " << int{c} << '\n'; 
} 

Tôi biết rằng chúng ta có thể đúc bằng:

  1. int(c)
  2. (int) c
  3. static_cast<int>(c)

Nhiệm vụ của tôi ions:

Q1: Có phải int{c} cách khác để truyền các loại dữ liệu?

Q2: Sau một số nghiên cứu trên mạng, tôi biết rằng C++ đúc là khác nhau và nó có trình biên dịch kiểm tra khả năng đúc tại thời gian biên dịch, nhưng sự khác biệt giữa 1 và 2 là gì? Và làm thế nào int{c} là khác nhau nếu nó chỉ là một cách đúc?

Q3: Có cách nào khác để chuyển đổi/truyền một cách rõ ràng không?

+3

Tôi nghĩ rằng các dấu ngoặc nhọn phải làm với khởi tạo danh sách, xem câu trả lời này http://stackoverflow.com/a/18222927/3110529 TL; DR: Danh sách khởi tạo không cho phép thu hẹp (§iso.8.5. 4) có nghĩa là nó sẽ bắt các chuyển đổi loại không an toàn. – Dillanm

+0

Cụ thể, nếu 'd' là' double' và 'double' có cùng kích thước với' uint64_t', 'static_cast (d)' và 'reinterpret_cast (d)' chuyển đổi theo các cách hoàn toàn khác nhau. C-style phôi không có tính linh hoạt đó; bạn sẽ cần phải gõ-pun thông qua một liên minh hoặc con trỏ để diễn giải lại các bit. – Davislor

Trả lời

7

int{c} một cách khác để truyền kiểu dữ liệu?

Có.T{value} tạo tạm thời loại Tdanh sách trực tiếp được khởi tạo với chỉ định được chỉ định-init-list được chỉ định. Dàn diễn viên này có lợi thế hơn T(value) trong đó T{value} có thể được sử dụng để tạo một mảng tạm thời. Điều đó sẽ được thực hiện như

int main() { 
    using int_array = int[5]; 
    for(auto e : int_array{1,2,3,4,5}) 
     std::cout << e; 
} 

Nó cũng đi kèm với sự báo trước rằng một chuyển đổi thu hẹp là một lỗi

int main() { 
    int(10000000000ll); // warning only, still compiles 
    int{10000000000ll}; // hard error mandated by the standard 
} 

Sau khi một số nghiên cứu trên mạng, tôi biết rằng C++ đúc là khác nhau và nó có trình biên dịch kiểm tra khả năng đúc tại thời gian biên dịch, nhưng sự khác biệt giữa 1 và 2 là gì?

Sự khác biệt lớn giữa T(value)(T)value là trong T(value), T phải là một từ duy nhất. Ví dụ

int main() { 
    unsigned int(10000000); // error 
    (unsigned int)10000000; // compiles 
} 

Q3: Có cách nào khác để chuyển đổi một cách rõ ràng/diễn viên?

Vâng trong C++ họ muốn bạn sử dụng C++ phôi đó là static_cast, reinterpret_cast, dynamic_cast, và const_cast. Những người được ưa thích hơn c phong cách diễn viên như một diễn viên phong cách c sẽ làm tất cả những người mà các phiên bản C + + có những hạn chế nhất định và đi kèm với đảm bảo nhất định.

3

Q1: Có. Nó gần như giống như một dàn diễn viên chức năng (int(c)), và hoạt động vì C++ 11 của uniform initialization. Tuy nhiên khởi tạo cú đúp không có một vài cảnh báo, ví dụ thu hẹp chuyển đổi (như long l = 5; char c{l};) sẽ tạo ra một cảnh báo.

Q2: 1 và 2 là tương đương, mặc dù có một số trường hợp mà một trong những hoạt động và không phải là khác.

// long long(c); // Breaks unless you make a typedef for 'long long' 
(long long)c; // Works fine 

template <class In, class Out> 
Out convert(const In& in) { 
    // return (Out)in; // Only works if 'In' is a primitive type 
    return Out(in); // Works regardless of the type of 'In' (assuming an appropriate constructor exists) 
} 

Q3: Ví dụ duy nhất về kiểu đúc kiểu C++ mà bạn đề cập là static_cast. Có khác C++ phôi cũng như:

  • dynamic_cast
  • reinterpret_cast
  • const_cast
5

int(c) là ++ phiên bản C của C-style cast (int)c. Lần đầu tiên, hãy thử một số const_cast<int>(c), sau đó (không thực hiện) một số static_cast<int>(c), sau đó là reinterpret_cast.

int{c} là một loài cá hơi khác một chút. Nghiêm túc, đây là khởi tạo danh sách và có các quy tắc nghiêm ngặt hơn. Đặc biệt, thu hẹp chuyển đổi không được phép, tức là

int x; 
char s{x}; // error 

Do đó, bạn nên sử dụng (thay vì phôi) trừ khi bạn biết rằng thu hẹp chuyển đổi có thể chấp nhận được.

Ngoài các loại nội trang khác, ngoài các phôi được đề cập ở trên, cũng có dynamic_cast.

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