使用可变参数模板绑定make_shared [英] bind make_shared with variadic template

查看:137
本文介绍了使用可变参数模板绑定make_shared的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写下面的工厂类,但我找不到正确的语法:

  template< class T,typename ... TArgs> 
class Factory {
public:
Factory(TArgs ... args){
creator_ = std :: bind(& std :: make_shared< T,TArgs ... >,args ...);
// ^^^这里有一些错误
}
std :: shared_ptr< T> Create()const {
return creator_();
}
private:
std :: function< std :: shared_ptr< T>()>创建者
}

这是我如何使用工厂:



< pre class =lang-cpp prettyprint-override> class Foo {
public:
Foo(bool value){}
};
class Bar {
public:
Bar(const std :: string& value){}
};
Factory< Foo,bool> f1(true);
Factory< Bar,std :: string> f2(string);

这是我在声明 f1 和 f2

 creator_ = std :: bind(& std :: make_shared< T,TArgs ...>,args ...); 
^

错误:不匹配'operator ='(操作数类型是'std :: function< std :: shared_ptr< Bar>()>'和'std :: _ Bind_helper< ; false,std :: shared_ptr< Bar>(*)(std :: basic_string< char>&&),std :: basic_string< char,std :: char_traits< char>,std :: allocator< char> ;&> :: type {aka std :: _ Bind< std :: shared_ptr< Bar>(*(std :: basic_string< char>))(std :: basic_string< char>&& ')
creator_ = std :: bind(& std :: make_shared< T,TArgs ...>,args ...);
^

正确的语法我必须使用 std :: bind

解决方案

std :: make_shared 如下声明:

  template<类T,类... Args> 
shared_ptr< T> make_shared(Args& ... args);

因此, std :: make_shared< T,TArgs ...> ; 将导致一个函数获取右值引用,它不会绑定到 args ... 。一个简单的解决方法是强制它通过折叠引用来获取引用值:

  creator_ = std :: bind ; std :: make_shared< T,TArgs& ...>,args ...); 
// ^

另一种方法是使用lambda,

  creator_ = [=](){return std :: make_shared< T>(args ...);}; 


I'm trying to write the following factory class, but I can't find the proper syntax:

template<class T, typename... TArgs>
class Factory {
 public:
  Factory(TArgs... args) {
    creator_ = std::bind(&std::make_shared<T, TArgs...>, args...);
    //      ^^^ some error around here
  }
  std::shared_ptr<T> Create() const {
    return creator_();
  }
 private:
  std::function<std::shared_ptr<T>()> creator_;
};

This is how I use the factory:

class Foo {
 public:
  Foo(bool value) {}
};
class Bar {
 public:
   Bar(const std::string& value) {}
};
Factory<Foo, bool> f1(true);
Factory<Bar, std::string> f2("string");

These are the errors I get when declaring f1 and f2:

error: no match for 'operator=' (operand types are 'std::function<std::shared_ptr<Foo>()>' and 'std::_Bind_helper<false, std::shared_ptr<Foo> (*)(bool&&), bool&>::type {aka std::_Bind<std::shared_ptr<Foo> (*(bool))(bool&&)>}')
   creator_ = std::bind(&std::make_shared<T, TArgs...>, args...);
            ^

error: no match for 'operator=' (operand types are 'std::function<std::shared_ptr<Bar>()>' and 'std::_Bind_helper<false, std::shared_ptr<Bar> (*)(std::basic_string<char>&&), std::basic_string<char, std::char_traits<char>, std::allocator<char> >&>::type {aka std::_Bind<std::shared_ptr<Bar> (*(std::basic_string<char>))(std::basic_string<char>&&)>}')
   creator_ = std::bind(&std::make_shared<T, TArgs...>, args...);
            ^

What is the correct syntax I must use with std::bind?

解决方案

std::make_shared is declared like this:

template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );

As such, std::make_shared<T, TArgs...> will result in a function taking rvalue references, which won't bind to args.... A simple fix for this is to force it to take lvalue references by collapsing the reference:

creator_ = std::bind(&std::make_shared<T,TArgs&...>, args...);
//                                            ^

An alternative is to use a lambda instead, which is more readable:

creator_ = [=](){return std::make_shared<T>(args...);};

这篇关于使用可变参数模板绑定make_shared的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆