Nếu tôi có một đối tượng a
hoặc là một mảng tích hợp hoặc loại lớp với operator []
phù hợp và loại trả lại của nó có thể được lập chỉ mục, tôi nên viết một hàm chung có thể lập chỉ mục tất cả chúng bằng một biến thể variadic như thế nào gọi thay vì khối khung được phân tách? Nói cách khác, tôi có thể làm cho biểu thức như:Làm cách nào để tạo một hàm lập chỉ mục xích dựa trên variadic?
a[i0][i1]...[iK]
và tôi muốn để có thể viết nó như là một chức năng duy nhất:
slice(a, i0, i1, ..., iK)
từ các quy tắc của C++ yêu cầu operator []
để làm việc trên lập luận đơn , làm cho nó ít tương thích với công cụ variadic. (Câu hỏi này được dựa trên một sợi Usenet nơi tôi thử hỏi một cái gì đó tương tự; kết thúc giải quyết chỉ có thể-lồng built-in mảng bản thân mình.)
Một đâm đầu tiên:
template < typename T, typename U >
constexpr
auto slice(T &&t, U &&u) noexcept(???) -> ???
{ return ce_forward<T>(t)[ ce_forward<U>(u) ]; }
template < typename T, typename U, typename V, typename ...W >
constexpr
auto slice(T &&t, U &&u, V &&v, W... &&w) noexcept(???) -> ???
{
return slice(ce_forward<T>(t)[ce_forward<U>(u)], ce_forward<V>(v),
ce_forward<W>(w)...);
}
Các ce_forward
chức năng mẫu là a constexpr
-marked std::forward
. (Một số điều trong tiêu chuẩn có thể được đánh dấu constexpr
không.) Tôi đang cố gắng tìm ra những thứ phù hợp để đưa vào kiểu trả về và các điểm đặc tả ngoại lệ. Một số trường hợp và hãy cẩn thận tôi biết là:
- Việc xây dựng trong
operator []
đòi hỏi một toán hạng là một dữ liệu con trỏ (hoặc tham chiếu mảng phân rã) và người kia là một liệt kê hoặc số nguyên kiểu. Các toán hạng có thể theo thứ tự. Tôi không biết liệu một toán hạng có thể được thay thế bằng một kiểu lớp với một chuyển đổi rõ ràng (không rõ ràng?) Thành một kiểu thích hợp hay không. - Loại lớp có thể xác định
operator []
là (các) hàm thành viên không tĩnh. Bất kỳ chức năng nào như vậy chỉ có thể có một tham số (bên cạnhthis
). - Nhà điều hành tích hợp không thể ném. (Trừ khi toán hạng có thể dựa trên một chuyển đổi UDT, chuyển đổi nói là điểm ném duy nhất có thể.) Hành vi không xác định do lỗi biên là vượt quá tầm nhìn của chúng tôi ở đây.
- Cuộc gọi lập chỉ mục cuối cùng có trả về tham chiếu giá trị l hay không, tham chiếu giá trị r hoặc giá trị phải được phản ánh trong loại trả về là
slice
. - Nếu cuộc gọi (cuối cùng?) Là giá trị bằng, thì
std::is_nothrow_move_constructible<ReturnType>::value
phải là OR cho đặc tả ngoại lệ. (Trả về tham chiếu lànoexcept
.) - Nếu toán tử tích hợp liên quan đến mảng, tham chiếu trả lại cho bước đó phải là tham chiếu giá trị r nếu mảng đó cũng là một tham chiếu. (Đây là loại lỗi bởi vì con trỏ, không giống như mảng, mất trạng thái giá trị l- so với giá trị r của chúng, do đó trở lại truyền thống sẽ luôn là tham chiếu giá trị l.)
- Đối với toán tử lập chỉ mục lớp, đảm bảo các phần loại trừ-spec và trả về tham chiếu đến cùng một tình trạng quá tải (nếu có nhiều hơn) mà nội dung chức năng sử dụng. Hãy cảnh giác với tình trạng quá tải chỉ khác nhau trong tiêu chuẩn của
this
(const
/volatile
/cả hai/không và/hoặc&
/&&
/không).
Nó phải là 'constexpr'? – kennytm
Đối với những gì tôi đang sử dụng nó cho, nó phải là 'constexpr' bất cứ khi nào có thể. – CTMacUser
Bạn đã xem xét việc đặt cùng một biểu thức như trong câu lệnh 'return' cho cả kiểu trả về và đặc tả' noexcept'? Ví dụ. 'noexcept (noexcept (std :: declval() [std :: declval ()])) -> decltype (std :: declval () [std :: declval ()])'. –