2017-07-10 14 views
11

Tôi đã cố gắng tìm hiểu các ví dụ sau đây mà tôi nhận được từ http://en.cppreference.com/w/cpp/utility/variant/visitSử dụng std :: thăm với mẫu variadic struct

#include <iomanip> 
#include <iostream> 
#include <string> 
#include <type_traits> 
#include <variant> 
#include <vector> 


using var_t = std::variant<int, long, double, std::string>; 

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; 
// what is this declaration imply??? 
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; 

int main() { 
    std::vector<var_t> vec = {10, 15l, 1.5, "hello"}; 


    for (auto& v: vec) { 
     std::visit(overloaded { 
      [](auto arg) { std::cout << arg << '\n'; }, 
      [](double arg) { std::cout << std::fixed << arg << '\n'; }, 
      [](const std::string& arg) { std::cout << std::quoted(arg) << '\n'; }, 
     }, v); 
    } 
} 

Có thể ai đó xin vui lòng giải thích cách này quá tải công trình struct? Đặc biệt những gì tôi không hiểu là tuyên bố sau đây.

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; 

Nếu không có tuyên bố này, trình biên dịch sẽ đưa ra các thông báo lỗi sau.

main.cpp: In function 'int main()': 
main.cpp:26:9: error: class template argument deduction failed: 
     }, v); 
     ^
main.cpp:26: confused by earlier errors, bailing out 

Mục đích: học tập

+0

Có [đề xuất] (http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0051r2.pdf) để thêm nội dung tương tự vào thư viện chuẩn như 'std :: quá tải' và [video dài 5 phút] (https://www.youtube.com/watch?v=1gNzhE-Tn40&list=PLs3KjaCtOwSZ2tbuV1hx8Xz-rFZTan2J1&index=50) về việc triển khai video này. –

Trả lời

10

Ai đó có thể xin giải thích như thế nào struct quá tải này hoạt động? Đặc biệt những gì tôi không hiểu là tuyên bố sau đây.

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; 

Đó là một user-defined deduction guide (liên kết đến các dự thảo làm việc).
Đó là một tính năng của ngôn ngữ được giới thiệu bởi bản sửa đổi mới nhất của tiêu chuẩn cùng với khấu trừ đối số mẫu lớp. Xem thêm here để biết thêm chi tiết và giải thích thân thiện với người dùng hơn.
Đây không phải là giải thích đúng, nhưng vì mục đích đơn giản, bạn có thể xem nó như một gợi ý bạn có thể đưa ra dẫn đến việc khấu trừ các đối số mẫu ra khỏi tập hợp các tham số cho hàm tạo.


Là một mặt lưu ý, here Tôi tìm thấy một ví dụ mà là khá rõ ràng và nó có giá trị sao chép nó qua:

template<typename T> 
struct Thingy { T t; }; 

Thingy(const char *) -> Thingy<std::string>; 

// ... 

Thingy thing{"A String"}; // thing.t is a `std::string`. 

Tín là dành cho @NicolBolas, một người sử dụng hoạt động ở đây trên SO. Thật không may tôi không thể tìm thấy câu trả lời mà từ đó ví dụ này đã được thực hiện.

+0

Cảm ơn rất nhiều ... –

+1

@PaulVarghese Bạn được chào đón. Đó là cách SO hoạt động: một câu hỏi mở, một người khác cố hết sức để trả lời. Hy vọng câu trả lời này có thể giúp bạn và độc giả trong tương lai. – skypjack

+3

Cần lưu ý rằng 'overload' hoạt động vì tổng hợp khởi tạo trong C++ 17 được mở rộng để có thể khởi tạo các lớp con cơ sở cũng như các thành viên. Ngoài ra, đó là "Nicol Bolas", [Tyrant of Worlds] (http://magic.wizards.com/en/story/planeswalkers/nicol-bolas), chứ không phải Nicolas. –

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