2016-06-15 11 views
6

Hôm nay tôi đang giúp với sau không chính xác đang mảnh (func được tuyên bố với int param, nhưng int* đã được thông qua như param thứ hai để std::thread constructor):Làm cách nào để diễn giải loại C++ này?

#include <thread> 

void func(int); 
int* ptr; 

void start() 
{ 
    std::thread t = std::thread(func, ptr); 
} 

Khi tôi cố gắng biên dịch này với gcc 5.3.0, nó in thông báo lỗi với loại sau:

class std::result_of<void (*(int*))(int)> 

Bây giờ tôi tự hỏi cách diễn giải kiểu được chuyển thành tham số là class std::result_of<>. Nó tương tự như con trỏ đến hàm (trong trường hợp này là void(*)(int)), nhưng với thêm (int*) sau dấu sao trong ngoặc đơn. Cách diễn giải loại này?

+0

Nếu 'func' yêu cầu' int' tại sao bạn chuyển một 'int *'? – NathanOliver

+0

Đây là lỗi trong mã mà tôi đã thấy hôm nay - có lẽ đây là lỗi đánh máy. –

+2

Một tuyên bố tương tự cho [this theo cdecl] (http://cdecl.ridiculousfish.com/?q=void+%28*f%28int*%29%29%28int%29). – ArchbishopOfBanterbury

Trả lời

5
void (*(int*))(int) 

là:

một chức năng mà phải mất một tham số duy nhất của loại int* như lợi nhuận

một con trỏ đến một chức năng mà phải mất một tham số duy nhất của loại int và trả

void


Nó tương tự như C/C++ tiêu chuẩn thư viện chức năng signal:

void (*signal(int sig, void (*func)(int)))(int); 

mà trả về một con trỏ đến một handler tín hiệu trước (đó là loại giống như các tham số func).

EDIT: Là Pete Becker pointed out in comment, khi được sử dụng với std::result_of, nó means something different, nhưng loại biểu thức chính nó vẫn là loại tôi mô tả, std::result_of chỉ diễn giải nó theo cách khác.

+0

Cảm ơn, tôi nhìn thấy nó ngay bây giờ. Tôi bắt đầu giải mã từ điểm sai và bị bối rối. –

+1

Vâng, đó là những gì nó sẽ có trong thế giới thực. Nhưng đó không phải là ** nghĩa là khi nó là kiểu đối số cho 'std :: result_of', nó loại bỏ ký pháp này để biểu diễn một kiểu có thể gọi và danh sách đối số của nó. –

+0

@PeteBecker Tôi nghĩ rằng OP đã nhầm lẫn về tuyên bố đó. Tôi không bao giờ nghe nói về 'std :: result_of' (bởi vì tôi đã học được C++ sau khi C++ 11 xuất hiện, vì vậy tôi chỉ sử dụng' decltype' và các tính năng mới), nhờ lời giải thích của bạn về nó. Tôi sẽ chỉnh sửa câu trả lời của mình. – PcAF

7

Điều này không đơn giản như mong đợi. std::result_of lạm dụng hệ thống kiểu để buôn lậu thông tin về một cuộc gọi hàm để nó có thể tìm ra loại trả về của cuộc gọi hàm đó.

Đối số cho std::result_of có dạng Fty(T1, T2, ...), trong đó Fty là loại có thể gọi và T1 vv là các loại đối số được gọi. Với thông tin đó, std::result_of có loại lồng nhau có tên là type là từ đồng nghĩa của loại trả về gọi một loại có thể gọi được với chữ ký Fty với các đối số của các loại đã cho. Phew, đó là một ngụm.

Vì vậy, trong result_of<void (*(int*))(int)> có hai phần đối số mẫu. Phần đầu tiên là void (*(int*)), là loại có thể gọi được đề cập. Trong trường hợp này, nó là một con trỏ trỏ tới hàm mất int* và trả về void. Phần thứ hai là (int), là danh sách loại cho các đối số được đề xuất.

Vì vậy, điều được nói là std::result_of đang được khởi tạo với một hàm có loại là void (*(int*)) và với danh sách đối số là (int). Và đó là vấn đề, như bạn chỉ ra: bạn không thể vượt qua một đối số của loại int đến một chức năng mà có một đối số của loại int*.

Bạn có vui không? (Ngẫu nhiên, đây là mẫu hackery cấp thấp không cần thiết nữa; decltype là một cách sạch hơn để tìm ra kiểu trả về của một cuộc gọi hàm).

+0

Vâng, điều đó thật khó hiểu ngay từ đầu. Cám ơn vì sự giải thích. –

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