Trong khi giải pháp của mfontanini hoạt động và tốt vì nó thực hiện việc tính toán chỉ số cột gia tăng tại thời gian biên dịch, tôi nghĩ rằng nó đáng giá chỉ ra rằng cũng có câu trả lời trực tiếp cho câu hỏi cách tăng int trong variadic gói mở rộng. (Thật không may nó dường như không hoạt động trên GCC do lỗi, xem báo trước ở cuối.)
Câu trả lời được dựa trên thực tế là trong khi các đánh giá đối số trong một cuộc gọi hàm không được kết thúc, các đánh giá của lập luận trong một danh sách khởi không:
(§8.5.4/4) trong thời hạn initializer-list của một chuẩn bị tinh thần-init-list, initializer-khoản, bao gồm bất kỳ mà kết quả từ việc mở rộng gói (14.5.3), được đánh giá theo thứ tự xuất hiện của chúng. Tức là, mọi tính toán giá trị và hiệu ứng phụ liên quan đến mệnh đề initializer-được sắp xếp trước khi tính toán giá trị và tác dụng phụ liên quan đến bất kỳ mệnh đề initializer nào theo sau trong danh sách được tạo bằng dấu phẩy của danh sách khởi tạo.
[Lưu ý: Thứ tự đánh giá này không phụ thuộc vào ngữ nghĩa của việc khởi tạo; ví dụ, nó áp dụng khi các phần tử của danh sách khởi tạo được hiểu là các đối số của một cuộc gọi hàm tạo, mặc dù thông thường không có ràng buộc trình tự trên các đối số của một cuộc gọi. - cuối note]
Do đó, nếu bạn chuyển đổi cuộc gọi chức năng của bạn vào một cái gì đó dựa trên một cú đúp-init-list, bạn sẽ nhận được hiệu quả mong muốn:
rowCallback(std::tuple<ColumnTypes...> { getColumn<ColumnTypes>(column++)... });
này khởi một std::tuple
sử dụng danh sách -initialization (chú ý các dấu ngoặc đơn { ... }
), do đó hiệu ứng phụ column++
sẽ được thực hiện theo thứ tự từ trái sang phải.
Nếu được viết như trên, điều này có nghĩa là bạn cần thay đổi rowCallback()
để làm cho nó chấp nhận std::tuple
thay vì danh sách đối số. Nếu bạn không thích điều này, bạn có thể tạo một hàm mẫu riêng biệt call_on_tuple(fun,tup)
, gọi hàm bất kỳ fun
trên các đối số phát sinh từ việc mở rộng tuple tup
. Tôi đã từng mô tả cách thực hiện điều này here hoặc nếu bạn thích, bạn có thể sử dụng rlxutil::call_on_tuple
từ my GitHub repository.
chức năng execute
của bạn sau đó trông như thế này:
template <typename... ColumnTypes>
void execute(function<void(ColumnTypes...)> rowCallback)
{
using std::tuple;
using rlxutil::call_on_tuple;
int column = 0;
call_on_tuple(rowCallback,
tuple<ColumnTypes...> { getColumn<ColumnTypes>(column++)... });
}
Nên biết trước: Đây là không hoạt động như mong đợi với GCC. Tôi tin rằng đây là do lỗi được báo cáo ở đây: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253.
Bạn đang đặt cột thành 0 ở mọi thời điểm. – jthill
@jthill: Đúng, trên mỗi hàng tôi khởi động lại từ cột số 0 khi trích xuất các giá trị từ hàng. –
Tại sao không thực hiện một hàm đơn giản có tham chiếu, gia số tham chiếu và trả về giá trị cũ? –