Tôi đang cố gắng để gõ xóa một đối tượng và chạy vào một chút của một vấn đề mà tôi hy vọng một ai đó ở đây có thể được có chuyên môn trong.C++ Type-tẩy xoá của một hàm mẫu sử dụng lambdas
tôi thiên đường' t đã có một vấn đề loại-erasing tùy ý không-templated chức năng; cho đến nay những gì tôi đã làm là tạo một bộ sưu tập các con trỏ hàm tùy chỉnh static
"ảo". Đây là tất cả được quản lý với lambdas không chụp, vì họ phân hủy thành con trỏ tự do chức năng:
template<typename Value, typename Key>
class VTable {
Value (*)(const void*, const Key&) at_function_ptr = nullptr;
// ...
template<typename T>
static void build_vtable(VTable* table) {
// normalizes function into a simple 'Value (*)(const void*, const Key&)'' type
static const auto at_function = [](const void* p, const Key& key) {
return static_cast<const T*>(p)->at(key);
}
// ...
table->at_function_ptr = +at_function;
}
// ...
}
(Có nhiều chức năng helper/aliases được bỏ qua cho ngắn gọn)
Đáng buồn cùng này cách tiếp cận không hoạt động với hàm template
.
Mong muốn của tôi là dành cho lớp kiểu xóa để có một cái gì đó tương tự như sau:
template<typename U>
U convert(const void* ptr)
{
return cast<U>(static_cast<const T*>(ptr));
}
nơi:
cast
là một chức năng miễn phí,U
là loại hạnh phúc được đúc thành,T
là loại bị xóa loại cơ bản đang được đúc từ vàptr
là con trỏ loại đã xóa theo cùng một thành ngữ ở trên để xóa loại.
[Chỉnh sửa: Vấn đề ở trên là T
không được biết đến từ chức năng convert
; hàm duy nhất biết về loại của T
trong ví dụ là build_vtable
. Điều này có thể yêu cầu thay đổi thiết kế]
Lý do điều này trở nên khó khăn là dường như không có cách nào đơn giản để xóa cả hai loại một cách độc lập. Kỹ thuật tẩy xóa kiểu cổ điển/thành ngữ của một lớp cơ sở không hoạt động ở đây, vì bạn không thể có chức năng a virtual
template
. Tôi đã thử nghiệm với một mô hình giống như khách truy cập với ít thành công cho các lý do tương tự như ở trên.
Có ai có kinh nghiệm về loại tẩy xóa có bất kỳ đề xuất hoặc kỹ thuật nào có thể được sử dụng để đạt được những gì Tôi đang cố gắng làm gì? Tốt hơn là trong mã C++ 14 phù hợp tiêu chuẩn. Hoặc, có lẽ là có thay đổi thiết kế có thể tạo điều kiện cho cùng một khái niệm mong muốn ở đây?
Tôi đã tìm kiếm câu trả lời này trong một thời gian ngắn và không có nhiều may mắn. Có một vài trường hợp tương tự như những gì tôi đang cố gắng làm, nhưng thường có đủ sự khác biệt mà các giải pháp dường như không áp dụng cho cùng một vấn đề (Vui lòng cho tôi biết nếu tôi sai).
Dường như hầu hết các bài đọc/blog về các chủ đề này đều có xu hướng đề cập đến kỹ thuật tẩy xóa cơ bản, nhưng không phải những gì tôi đang tìm kiếm ở đây!
Cảm ơn!
Lưu ý: vui lòng không khuyên bạn nên Boost. Tôi đang ở trong một môi trường mà tôi không thể sử dụng thư viện của họ, và không muốn giới thiệu sự phụ thuộc đó vào cơ sở mã.
Không thể 'cast' là hàm functor và sau đó gọi nó là 'cast (tag {}, truyền (tag {}, ptr))'? –
Jarod42
@ Jarod42 Vấn đề là 'T' không được biết đến từ bên trong' chuyển đổi', vì vậy nó không đơn giản như việc tạo ra một 'tag' tại thời điểm đó. Hàm duy nhất trong ví dụ biết loại 'T' là' build_vtable' –
Bitwize
Đầu tiên, nó không phải là một hàm 'mẫu'; nó là một hàm 'mẫu'.Từ ngữ là điều quan trọng cần hiểu ở đây. Vì vậy, nó không phải là một chức năng thực tế. Hàm thực tế là 'chuyển đổi ' như Yakk mô tả. Vì vậy, bạn sẽ cần 'convert_U_function_ptr' bên trong' VTable' của bạn cho mỗi 'U' loại – zahir