Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 工厂函数返回带有自定义删除器的唯一\u ptr_C++_C++14_Unique Ptr - Fatal编程技术网

C++ 工厂函数返回带有自定义删除器的唯一\u ptr

C++ 工厂函数返回带有自定义删除器的唯一\u ptr,c++,c++14,unique-ptr,C++,C++14,Unique Ptr,我正在创建一个helper函数,用于加载共享lib,并使用自定义deleter(模块销毁函数)将结果放入std::unique_ptr 当我没有设置自定义删除器时,这可以很好地工作,但一旦我添加它们,我就会得到一个错误,即无法推断自定义删除器的类型(这是公平的) 问题是,如果我在调用函数时指定deleter类型的位置,它将看起来非常丑陋 问题是,我的函数如何自动推断自定义删除器的类型?我应该如何声明结果的std::unique\u ptrs的std::vector 我的代码(我也愿意接受关于代码

我正在创建一个helper函数,用于加载共享lib,并使用自定义deleter(模块销毁函数)将结果放入
std::unique_ptr

当我没有设置自定义删除器时,这可以很好地工作,但一旦我添加它们,我就会得到一个错误,即无法推断自定义删除器的类型(这是公平的)

问题是,如果我在调用函数时指定deleter类型的位置,它将看起来非常丑陋

问题是,我的函数如何自动推断自定义删除器的类型?我应该如何声明结果的
std::unique\u ptr
s的
std::vector

我的代码(我也愿意接受关于代码的任何建议):

模板
std::unique_ptr openLib(const std::string和lib_路径,
const std::string&csym=“create”,
const std::string&dsym=“destroy”)
{
无效*手柄;
if(!(handle=dlopen(lib_path.c_str(),RTLD_LAZY)))
{

std::cerr编写删除器类型和工厂

using deleter = void();
using ptr_deleter = deleter*;
struct lib_unloader {
  deleter* del = 0;
  void operator()(void*)const { if (del) del(); }
  explicit operator bool() const { return del; }
};
lib_unloader get_lib_unloader( void* handle, char const* destroy_name ) {
  auto del = ptr_deleter( dlsym( handle, destroy_name ) );
  return {del};
}
template<class T>
using lib_up = std::unique_ptr< T, lib_unloader >;

template<class T>>
lib_up<T> openLib(const std::string &lib_path,
                       const std::string &csym = "create",
                       const std::string &dsym = "destroy")
{
  void *handle;
  if (!(handle = dlopen(lib_path.c_str(), RTLD_LAZY)))
  {
    std::cerr << "dlopen " << dlerror() << std::endl;
    return nullptr;
  }
  T *(*create)();
  if (!(create = (T * (*)()) dlsym(handle, csym.c_str())))
  {
    std::cerr << "dlsym " << csym << dlerror() << std::endl;
    return nullptr;
  }
  auto destroy = get_lib_unloader( handle, dsym.c_str() );
  if (!destroy) {
    std::cerr << "dlsym " << dsym << dlerror() << std::endl;
    return nullptr;
  }
  return {create(), destroy};
}
使用deleter=void();
使用ptr_deleter=deleter*;
结构库卸载程序{
deleter*del=0;
void运算符()(void*)常量{if(del)del();}
显式运算符bool()常量{return del;}
};
lib_卸载程序get_lib_卸载程序(void*句柄,char const*destroy_名称){
自动删除=ptr_deleter(dlsym(句柄,销毁名称));
返回{del};
}
模板
使用lib_up=std::unique_ptr;
模板>
lib\u up openLib(const std::string和lib\u路径,
const std::string&csym=“create”,
const std::string&dsym=“destroy”)
{
无效*手柄;
if(!(handle=dlopen(lib_path.c_str(),RTLD_LAZY)))
{

std::cerr编写删除器类型和工厂

using deleter = void();
using ptr_deleter = deleter*;
struct lib_unloader {
  deleter* del = 0;
  void operator()(void*)const { if (del) del(); }
  explicit operator bool() const { return del; }
};
lib_unloader get_lib_unloader( void* handle, char const* destroy_name ) {
  auto del = ptr_deleter( dlsym( handle, destroy_name ) );
  return {del};
}
template<class T>
using lib_up = std::unique_ptr< T, lib_unloader >;

template<class T>>
lib_up<T> openLib(const std::string &lib_path,
                       const std::string &csym = "create",
                       const std::string &dsym = "destroy")
{
  void *handle;
  if (!(handle = dlopen(lib_path.c_str(), RTLD_LAZY)))
  {
    std::cerr << "dlopen " << dlerror() << std::endl;
    return nullptr;
  }
  T *(*create)();
  if (!(create = (T * (*)()) dlsym(handle, csym.c_str())))
  {
    std::cerr << "dlsym " << csym << dlerror() << std::endl;
    return nullptr;
  }
  auto destroy = get_lib_unloader( handle, dsym.c_str() );
  if (!destroy) {
    std::cerr << "dlsym " << dsym << dlerror() << std::endl;
    return nullptr;
  }
  return {create(), destroy};
}
使用deleter=void();
使用ptr_deleter=deleter*;
结构库卸载程序{
deleter*del=0;
void运算符()(void*)常量{if(del)del();}
显式运算符bool()常量{return del;}
};
lib_卸载程序get_lib_卸载程序(void*句柄,char const*destroy_名称){
自动删除=ptr_deleter(dlsym(句柄,销毁名称));
返回{del};
}
模板
使用lib_up=std::unique_ptr;
模板>
lib\u up openLib(const std::string和lib\u路径,
const std::string&csym=“create”,
const std::string&dsym=“destroy”)
{
无效*手柄;
if(!(handle=dlopen(lib_path.c_str(),RTLD_LAZY)))
{

std::cerr为什么
destroy
返回一个
T*
?我想我复制和粘贴创建部分有点太快了,编辑了;)这里实际播放的是什么卷
T
?看起来
T
应该是
void
而这根本不需要是一个模板?为什么
destroy
返回一个
T*
?我想我复制和粘贴create部分的速度有点太快了,编辑了;)这里实际播放的是什么滚动?似乎
T
应该是
void
,而这根本不需要是一个模板?因此,如果我要创建生成的唯一\u ptr的向量,我应该包括“lib\u unloader”吗在模板定义中,如so
std::vector>
或no?关于泄漏句柄,是否也将其包装在唯一的\u ptr中,以便在其超出范围时删除自身是一个好主意?@ThéoChampion是的,这是您唯一的ptr的类型。对于句柄,我会编写一个更好的。它可能包含一个
唯一的\u ptr
ketched提出了一个解决方案,其中我没有将其作为对象,只是一个
unique\u ptr
。我注意到在上面的代码中,
get\u sym
返回一个
t*(**)()
正常吗?我认为这是在调用
ptr\u deleter
时导致SEG故障的原因end@thro固定的,不测试的代价。;)所以,如果我要创建一个生成的唯一\u ptr的向量,我应该包括“lib\u卸载器”吗在模板定义中,如so
std::vector>
或no?关于泄漏句柄,是否也将其包装在唯一的\u ptr中,以便在其超出范围时删除自身是一个好主意?@ThéoChampion是的,这是您唯一的ptr的类型。对于句柄,我会编写一个更好的。它可能包含一个
唯一的\u ptr
ketched提出了一个解决方案,其中我没有将其作为对象,只是一个
唯一的\u ptr
。我注意到在上面的代码中,
get\u sym
返回一个
t*(**)(
)是否正常?我认为这是在end@thro固定,不测试的价格。;)
using libhandle_ptr = std::unique_ptr<void, std::integral_constant<int(*)(void*), dlclose>>;

libhandle_ptr make_libhandle(const char* filename, int flags) {
  return libhandle_ptr( dlopen(filename, flags) );
}
template<class T>
T* get_sym( libhandle_ptr const& handle, const char* symbol ) {
  if (!handle || !symbol) return nullptr;
  return static_cast<T*>( dlsym( handle.get(), symbol ) );
}
lib_unloader get_lib_unloader( libhandle const& handle, char const* destroy_name ) {
  auto del = get_sym<deleter>( handle, destroy_name );
  return {del};
}
template<class T>>
lib_up<T> openLib( libhandle_ptr const& handle,
                       const char* csym = "create",
                       const char* dsym = "destroy")
{
  if (!handle)
    return {};
  auto create = get_sym<T*()>( handle, csym );
  if (!create)
  {
    std::cerr << "dlsym " << csym << dlerror() << std::endl;
    return {};
  }
  auto destroy = get_lib_unloader( handle, dsym.c_str() );
  if (!destroy) {
    std::cerr << "dlsym " << dsym << dlerror() << std::endl;
    return {};
  }
  return {create(), destroy};
}