C++ 静态成员函数与 lambda 开销
C++ static member function vs lambda overhead
我有一些模板化的基础class
template<typename Derived>
class Base { };
并希望将它的派生实例存储在列表中。
为此,我使用 using derived_handle = std::unique_ptr<void, void(*)(void*)
别名。
当我现在将派生实例添加到列表时,我会使用静态成员函数作为删除器
class foo {
template<typename Derived, typename... Args>
void add_base(Args&&... args) {
auto derived = derived_handle{new Base{std::forward<Args>(args)..., &foo::_deleter<Derived>};
_derived.emplace_back(std::move(derived));
}
private:
template<typename Baser>
void _deleter(void* base) {
delete static_cast<Base*>(base);
}
std::vector<derived_handle> _derived{};
};
或 lambda
class foo {
template<typename Derived, typename... Args>
void add_base(Args&&... args) {
auto deleter = [](auto* derived){
delete static_cast<Derived*>(derived);
}
auto derived = derived_handle{new Base{std::forward<Args>(args)..., std::move(deleter)};
_derived.emplace_back(std::move(derived));
}
private:
std::vector<derived_handle> _derived{};
};
我应该注意 advantages/disadvantages 的 lambda 版本吗?
框架挑战时间到了!
您在该代码中做出了一些错误的决定。大多数使用 unique_ptr
的人,即使在多态上下文中,也根本不需要自定义删除器。你这样做的唯一原因是因为你的类型擦除,而那只是因为 Base<A>
和 Base<B>
是不相关的类型。
如果您真的需要 Base<T>
,让它继承自 实际 多态(和非模板化)基 class 和虚拟析构函数。那么你就不需要 unique_ptr<void>
(一种非常糟糕的代码味道),你实际上可以以类型安全的方式使用你的列表。
我有一些模板化的基础class
template<typename Derived>
class Base { };
并希望将它的派生实例存储在列表中。
为此,我使用 using derived_handle = std::unique_ptr<void, void(*)(void*)
别名。
当我现在将派生实例添加到列表时,我会使用静态成员函数作为删除器
class foo {
template<typename Derived, typename... Args>
void add_base(Args&&... args) {
auto derived = derived_handle{new Base{std::forward<Args>(args)..., &foo::_deleter<Derived>};
_derived.emplace_back(std::move(derived));
}
private:
template<typename Baser>
void _deleter(void* base) {
delete static_cast<Base*>(base);
}
std::vector<derived_handle> _derived{};
};
或 lambda
class foo {
template<typename Derived, typename... Args>
void add_base(Args&&... args) {
auto deleter = [](auto* derived){
delete static_cast<Derived*>(derived);
}
auto derived = derived_handle{new Base{std::forward<Args>(args)..., std::move(deleter)};
_derived.emplace_back(std::move(derived));
}
private:
std::vector<derived_handle> _derived{};
};
我应该注意 advantages/disadvantages 的 lambda 版本吗?
框架挑战时间到了!
您在该代码中做出了一些错误的决定。大多数使用 unique_ptr
的人,即使在多态上下文中,也根本不需要自定义删除器。你这样做的唯一原因是因为你的类型擦除,而那只是因为 Base<A>
和 Base<B>
是不相关的类型。
如果您真的需要 Base<T>
,让它继承自 实际 多态(和非模板化)基 class 和虚拟析构函数。那么你就不需要 unique_ptr<void>
(一种非常糟糕的代码味道),你实际上可以以类型安全的方式使用你的列表。