2015-06-18 16 views
5

Tôi đã đọc những câu hỏi liên quan sau đây:Tại sao không phải là tiêu chuẩn :: result_of <int(int)> :: loại hợp lệ?

  1. std::result_of simple function
  2. decltype, result_of, or typeof?

the page on std::result_of at cppreference.com.

Tất cả trong số họ dường như chỉ ra rằng tôi nên có thể sử dụng:

std::result_of<int(int)>::type v1 = 10; 

Tuy nhiên, khi tôi đã cố gắng xây dựng các chương trình sau đây sử dụng g ++ 4.9.2

#include <type_traits> 

int foo() 
{ 
    return 0; 
} 

int main() 
{ 
    std::result_of<int(int)>::type v1 = 10;   // LINE A 
    std::result_of<decltype(foo)>::type v2 = 20;  // LINE B 
    return 0; 
} 

tôi nhận được thông báo lỗi cho "LINE A" và "LINE B". Các thông báo lỗi là:

socc.cc: In function ‘int main()’: 
socc.cc:10:5: error: ‘type’ is not a member of ‘std::result_of<int(int)>’ 
    std::result_of<int(int)>::type v1 = 10; 
    ^
socc.cc:11:5: error: ‘type’ is not a member of ‘std::result_of<int()>’ 
    std::result_of<decltype(foo)>::type v2 = 20; 
    ^

Lệnh tôi sử dụng để biên dịch:

g++ -std=c++11 -Wall socc.cc -o socc 

FWIW, sử dụng

typename std::result_of<int(int)>::type v1 = 10; 
typename std::result_of<decltype(foo)>::type v2 = 20; 

không tạo sự khác biệt.

Có vẻ như tôi không hiểu cách result_of được cho là được sử dụng.

Bạn có thể giải thích tại sao tôi gặp phải lỗi trình biên dịch không?

+1

Bạn có nghĩa là 'result_of <(int (int)) (int)>'? –

+0

lưu ý rằng 'result_of' đã thay đổi từ C++ 11 thành C++ 14, bạn có thể xác nhận bạn đang hỏi về phiên bản C++ 11 không? –

+0

@KerrekSB, Không, ý tôi là 'result_of <(int(int))>'. Đó có thể là phần thiếu hiểu biết của tôi về 'result_of'. Bạn sẽ giải thích về điều đó? –

Trả lời

10

Như đã nêu trong liên kết bạn đã đăng, phần đầu tiên của đối số là result_of phải là một loại có thể gọi hoặc tham chiếu đến một hàm.

Giả sử bạn có một

struct Callable 
{ 
    int operator()(double); 
    void operator()(int); 
}; 

sau đó result_of giúp bạn xác định kiểu trả về, nếu bạn biết loại của các đối số. Đối với ví dụ trên:

result_of<Callable(int)>::type == void ... per definition 
result_of<Callable(double)>::type == int ... per definition 
result_of<Callable(char)>::type == void ... the int-overload matches better 
result_of<Callable(float)>::type == int ... the double-overload matches better 

Để tìm ra kiểu trả về của hàm foo bạn sẽ phải đi qua một tài liệu tham khảo chức năng:

result_of<decltype(foo)&()>::type == int 

Nhưng điều này có vẻ hơi xoắn như bạn có thể trực tiếp viết

decltype(foo()) == int 
12

Bạn có vẻ giả định std::result_of<R(Args...)>::type chỉ đơn giản là R - tức là, loại kết quả của hàm có chữ ký R(Args...). Nhưng std::result_of<F(Args...)>::type là kết quả của việc gọi một thể hiện kiểu F với các đối số thuộc loại Args....

Vì vậy, std::result_of<int(int)>::type không có ý nghĩa - int đối tượng không thể gọi được.

Xin vui lòng, đọc cppreference nữa :)

2

Để sử dụng result_of, loại cung cấp phải là một loại chức năng mà kiểu trả về là kiểu của một Callable và danh sách tham số chứa các loại của các đối số để gọi nó là với. result_of<int(int)> do đó yêu cầu "tôi sẽ nhận được loại nào khi tôi gọi declval<int>() với đối số declval<int>()". Câu trả lời là không có loại, bởi vì int không phải là một loại chức năng.

Dưới đây là một đoạn trích từ Bảng 57:

Nếu biểu thức INVOKE(declval<Fn>(), declval<ArgTypes>()...) được hình thành tốt khi đối xử như một toán hạng unevaluated (khoản 5), các loại thành viên typedef sẽ đặt tên cho loại decltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...)); cách khác, sẽ không có thành viên type

với chức năng foo, bạn có thể sử dụng:

std::result_of_t<decltype((foo))()> v1 = 10; 
std::result_of_t<decltype(&foo)()> v2 = 10; 
+0

Đó là bắt đầu có ý nghĩa :) Cho 'foo' trong câu hỏi của tôi tại sao không' result_of :: type' làm việc? –

+0

@RSahu Bởi vì điều đó tuyên bố một hàm trả về một hàm, mà bạn không thể làm được. Bạn có thể thay 'decltype (foo) &()' hoặc 'decltype (foo) *()'. – 0x499602D2

+0

Không hoạt động. Xem http://ideone.com/lMfDOa. –

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