2009-10-30 38 views

Trả lời

50

Không có sự khác biệt; theo tiêu chuẩn (§5.2.3):

Trình định dạng kiểu đơn giản (7.1.5) tiếp theo là danh sách biểu thức được tạo thành một giá trị của kiểu được chỉ định cho danh sách biểu thức. Nếu danh sách biểu thức là một biểu thức duy nhất, biểu thức chuyển đổi kiểu là tương đương (trong định nghĩa và nếu được định nghĩa trong nghĩa) cho biểu thức truyền tương ứng (5.4).

Vì câu hỏi đã chỉ ra sự khác biệt giữa type(value)(type)value, hoàn toàn không có sự khác biệt.

Nếu và chỉ khi bạn đang xử lý danh sách được phân cách bằng dấu phẩy giá trị có thể có sự khác biệt. Trong trường hợp này:

Nếu danh sách biểu thức chỉ định nhiều hơn một giá trị, loại phải là lớp có hàm tạo được khai báo phù hợp (8.5, 12.1) và biểu thức T (x1, x2, ...) tương đương với khai báo T t (x1, x2, ...); đối với một số biến tạm thời được phát minh t, với kết quả là giá trị của t là giá trị rvalue.

Như Troubadour đã chỉ ra, có một số loại tên nhất định mà phiên bản type(value) chỉ đơn giản là không biên dịch. Ví dụ:

char *a = (char *)string; 

sẽ biên dịch, nhưng:

char *a = char *(string); 

sẽ không. Cùng loại với tên khác (ví dụ: được tạo với một số typedef) có thể hoạt động:

typedef char *char_ptr; 

char *a = char_ptr(string); 
+0

Chỉ dành cho các loại được cài sẵn. – Troubadour

+7

Um, không có sự khác biệt nào. +1 –

+2

Vâng, có thể :) Nhưng những gì về các loại con trỏ untypedef'ed? – Troubadour

13

Không có sự khác biệt; tiêu chuẩn C++ (ấn bản năm 1998 và 2003) rõ ràng về điểm này. Hãy thử chương trình sau, đảm bảo bạn sử dụng trình biên dịch tuân thủ, chẳng hạn như bản xem trước miễn phí tại http://comeaucomputing.com/tryitout/.

#include <cstdlib> 
#include <string> 
int main() { 
    int('A'); (int) 'A'; // obvious 
    (std::string) "abc"; // not so obvious 
    unsigned(a_var) = 3; // see note below 
    (long const&) a_var; // const or refs, which T(v) can't do 
    return EXIT_SUCCESS; 
} 

Lưu ý: unsigned(a_var) khác, nhưng hiển thị một cách chính xác mã thông báo có thể có ý nghĩa khác. Nó đang khai báo một biến có tên là a_var của loại unsigned, và không phải là một diễn viên nào cả. (Nếu bạn đã quen thuộc với các con trỏ tới chức năng hoặc mảng, hãy xem xét làm thế nào bạn phải sử dụng một dấu ngoặc xung quanh p trong một loại như void (*pf)() hoặc int (*pa)[42].)

(Cảnh báo được sản xuất từ ​​các báo cáo không sử dụng các giá trị và trong một chương trình thực sự gần như chắc chắn là một lỗi, nhưng mọi thứ vẫn hoạt động. Tôi chỉ không có trái tim để thay đổi nó sau khi làm mọi thứ xếp hàng.)

+0

Định dạng mã đẹp, được dự định? – squelart

+2

@squelart: Không phải lúc đầu, nhưng một khi nó đến gần tôi đã làm việc đó, và không có trái tim để thay đổi nó để loại bỏ các cảnh báo. –

6

Không có sự khác biệt khi cả hai đều là phôi, nhưng đôi khi 'loại (giá trị)' không phải là một diễn viên.

Dưới đây là một ví dụ từ tiêu chuẩn dự thảo N3242, phần 8.2.1:

struct S 
{ 
    S(int); 
}; 

void foo(double a) 
{ 
    S w(int(a)); // function declaration 
    S y((int)a); // object declaration 
} 

Trong trường hợp này 'int (a)' không phải là một dàn diễn viên vì 'a' không phải là một giá trị, nó là một tham số tên được bao quanh bởi dấu ngoặc đơn thừa. Tài liệu này khẳng định

Sự mơ hồ phát sinh từ sự tương đồng giữa một dàn diễn viên chức năng kiểu và ra tuyên bố nêu tại 6.8 cũng có thể xảy ra trong bối cảnh của một bản tuyên bố. Trong bối cảnh đó, sự lựa chọn nằm giữa một khai báo hàm với một bộ ngoặc đơn dư thừa xung quanh một tham số tên và khai báo đối tượng với một kiểu hàm kiểu làm bộ khởi tạo . Cũng giống như những sự mơ hồ được đề cập trong 6.8, độ phân giải là xem xét bất kỳ cấu trúc nào có thể có thể là tuyên bố tuyên bố.

1

Trong c không có type (value), trong khi ở c/C++ cả hai type (value)(type) value đều được cho phép.

0

Để minh họa cho lựa chọn của bạn trong C++ (chỉ có một có một kiểm tra an toàn)

#include<boost/numeric/conversion/cast.hpp> 

using std::cout; 
using std::endl; 
int main(){ 

    float smallf = 100.1; 

    cout << (int)smallf << endl; // outputs 100 // c cast 
    cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast 

    cout << static_cast<int>(smallf) << endl; // outputs 100 
// cout << static_cast<int&>(smallf) << endl; // not allowed 
    cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563 
    cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100 

    float bigf = 1.23e12; 

    cout << (int)bigf << endl; // outputs -2147483648 
    cout << int(bigf) << endl; // outputs -2147483648 

    cout << static_cast<int>(bigf) << endl; // outputs -2147483648 
// cout << static_cast<int&>(bigf) << endl; // not allowed 
    cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083 
    cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion 
} 
Các vấn đề liên quan