2012-11-08 29 views
11

Tôi muốn viết một mẫu có thể lấy làm tham số kiểu trả về của hàm mà nó đang được khởi tạo.Có cách nào để lấy kiểu trả về của "hàm hiện tại"

Ví dụ, giả sử tôi đã một lớp templated Result:

template<type T> 
class Result { 
    T _result_value; 
    T& operator=(T that); 
    ~Result(); 
} 

Sẽ có nhiều chuyên ngành cho lớp này. Trong destructor tôi muốn đăng nhập kiểu trả về, và trong bài tập operator= tôi muốn kiểm tra và xác nhận các giá trị lỗi.

Lý tưởng nhất, tôi muốn để có thể có một định nghĩa:

#define RESULT Result< /* decltype magic for type of current function */ > 

vì vậy tôi có thể sử dụng nó:

HFILE MyOpenFile(...) { 
    RESULT result; 
} 

... mà sẽ được rút ra để Result<HFILE>. Đây là một ví dụ đơn giản: viết RESULT thay vì Result<HFILE> không phải là một vấn đề lớn, nhưng có những trường hợp khác mà kiểu trả về của hàm hiện tại không dễ dàng thu được.

+0

bạn có thể sử dụng http://en.wikipedia.org/wiki/Decltype? – bobah

+1

Tôi đoán bạn sẽ ít nhất phải chuyển tên hàm thành macro (ví dụ: 'RESULT (MyOpenFile)') và trong trường hợp quá tải, bạn vẫn gặp phải sự mơ hồ. Ngay cả [nhận được một con trỏ đến chức năng hiện tại] (http://stackoverflow.com/q/2154852/1468366) là khó khăn, và nhận được một con trỏ chính xác gõ có vẻ không thể mà không đặt tên lại chức năng. – MvG

+0

@MvG, bạn có thể nhận được sự mơ hồ quá tải bằng cách chuyển đến 'decltype' hàm + thông số, ví dụ: 'decltype (foo (b))', 'decltype (foo (a, b))' sẽ giải quyết chính xác. Tuy nhiên, đó là một nỗi đau .. – Nim

Trả lời

4

Không. Không có gì trong C++ đề cập đến "hàm hiện tại". Gần nhất là __func__ nhưng đó là một chuỗi chữ. Do đó, không có gì để chuyển đến decltype.

Không phải bạn cần nó, với auto.

3

Không thể từ bên trong một hàm vì không có đối tượng chuyên dụng trong bộ nhớ đại diện cho nó có thể được tham chiếu để suy ra loại. Có thể cho các lớp học, qua decltype(*this).

3

Cách di động nhất mà tôi có thể nghĩ đến là sử dụng decltype:

#define RESULT(func, ...) Result<decltype(func(__VA_ARGS__))> 

int main(int argc, char **argv) { 
    RESULT(main, argc, argv) result; // same as `Result<int> result;` 
} 

Nhưng điều này buộc bạn phải vượt qua các tên hàm và mọi lý luận cần thiết để các RESULT vĩ mô. Tôi không nghĩ rằng điều này là tránh được, bởi vì không có di động (và thường không phải là một trình biên dịch cụ thể) cách để có được một định danh cho các chức năng hiện tại và/hoặc các đối số thông qua. Các đối số đã vượt qua vấn đề nhờ vào sự mơ hồ quá tải.

Đây là SSCCE: http://ideone.com/cPTjjF

+2

bạn không cần kinh doanh varargs, chỉ cần xác định 'RESULT' là' RESULT (f) Result 'và sau đó sử dụng như' RESULT (chính (argc, argv)) '... – Nim

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