2013-08-09 27 views
6

Bất kỳ giải pháp nào tốt hơn là viết thủ công một tiện ích như thế này?Làm cách nào để lặp qua std :: tuple?

template <size_t> struct SizeT { }; 

template < typename TupleType, typename ActionType > 
inline void TupleForEach(TupleType& tuple, ActionType action) 
{ 
    TupleForEach(tuple, action, SizeT<std::tuple_size<TupleType>::value>()); 
} 

template < typename TupleType, typename ActionType > 
inline void TupleForEach(TupleType& tuple, ActionType action, SizeT<0>) { } 

template < typename TupleType, typename ActionType, size_t N > 
inline void TupleForEach(TupleType& tuple, ActionType action, SizeT<N>) 
{ 
    TupleForEach(tuple, action, SizeT<N-1>()); 
    action(std::get<N-1>(tuple)); 
} 

Để được sử dụng như thế này:

std::tuple<char, int, double> tt; 
TupleForEach(tt, (boost::lambda::_1 = 5)); 
+1

Tiêu chí của bạn cho "tốt hơn" là gì? – Casey

+0

@Casey - Triển khai thư viện trong 'std' hoặc' boost'; nếu không, sau đó thực hiện với ít mã thì điều này; hoặc có thể có vấn đề trong việc triển khai này. – Vahagn

Trả lời

1

Mặc dù có một số câu trả lời cung cấp trong một previous, related question (và một trong những bạn cung cấp cho mình), ấn tượng ban đầu của tôi là sự cần thiết phải lặp qua các tuple có thể là một sự phản ánh của một thiết kế nghèo nàn.

Như bạn biết, lý do tại sao chúng tôi không thể lặp qua một std::tuple sử dụng thuật toán C++ chuẩn là vì std::tuple không hoàn thành Container concept. Và, chính xác, nó không hoàn thành khái niệm như vậy bởi vì std::tuple s không có value_type (chúng không đồng nhất). Tôi biết rằng bạn đã sử dụng một bộ dữ liệu vì bạn không muốn tạo loại đa hình của riêng mình và lưu trữ nó trong một vùng chứa tiêu chuẩn (ví dụ: std::vector<std::shared_ptr<BaseClass>>). Điều này giúp bạn có được lợi ích nhanh chóng. Nhưng điều đó cũng có nghĩa là bạn đã tự nguyện từ bỏ những lợi thế của Container s.

Nó có thể hoạt động, nhưng nó bằng cách nào đó cảm thấy bị ép buộc và không tự nhiên: nếu bạn cần ngữ nghĩa của container, tại sao không sử dụng một container? Nếu bạn cần ngữ nghĩa đa hình, tại sao không sử dụng một loại đa hình?

Có lẽ tôi đang phóng đại, nhưng đây là ấn tượng ban đầu của tôi.

+0

Lý do tại sao tôi đã không tạo một lớp cơ sở đa hình cho các loại trong bộ dữ liệu không phải là một whim :) Các kiểu này là từ loại của bên thứ ba, vì vậy người sử dụng chúng, chắc chắn, không nhất thiết là người duy trì chúng. Các kiểu này, tuy nhiên, chia sẻ một khái niệm chung, do đó một số hoạt động có giá trị đối với mỗi khái niệm, do đó, một người lưu trữ một loạt các đối tượng thuộc loại này, có thể muốn thực hiện các hoạt động đó trên các đối tượng đó. – Vahagn

+4

Hơn nữa, hãy xem xét một tuple 'char',' int' và 'double'. Hoặc một tuple của một số con trỏ. Trong trường hợp đầu tiên, ví dụ: hoạt động hợp lệ của việc thiết lập các thành viên tuple về 0 và trong trường hợp thứ hai, ví dụ: một hoạt động hợp lệ của việc thiết lập các thành viên tuple thành 'nullptr', nhưng chắc chắn trong C++ nó là một loại vô nghĩa để xem xét một lớp cơ sở cho tất cả các loại số học hoặc một lớp cơ sở cho tất cả các kiểu con trỏ. – Vahagn

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