C ++如何使用std ::绑定/的std ::函数参考模板化功能(C++ How to Refer

2019-07-19 09:01发布

如果你有一个模板类或模板函数(或两者的组合),你怎么绑定该功能,(保留模板类型参数)?

我给出关于以下职位基本语法一些帮助,结合显式模板类型参数的功能,但失去了在这个过程中提供的模板类型参数的能力。

是否有可能得到这个工作,所以它仍然可以提供模板类型参数与未来的呼叫?

清理这个代码很多,但它显然不能编译,因为我无法找到正确的语法,(有没有这样做的任何方式)?

去掉了“矢量”的要求,以简化这个:

谢谢您的帮助!

#include <functional>
#include <vector>
#include <string>

/***************************************/
template <typename CommandTemplateType>
class Storage
{
  public:
   // No idea how to define this vector to allow Template Parameters
   // static std::vector<std::function<void<ParameterTemplateType>
   //     (std::shared_ptr<ParameterTemplateType>)>> Functions;

   // I really don't need the collection, a single member would kick start my research:
   static std::function<void<ParameterTemplateType>(std::shared_ptr<ParameterTemplateType>)> Function;

  template <typename ParameterTemplateType>
  static void Execute(ParameterTemplateType parameter)
  {
     // Look up index, or loop through all.. 
     // I am trying to invoke the bound function with a template param:
     // Functions[index]<ParameterTemplateType>(parameter);
     // preferably, just:  
     Function<ParameterTempalteType>(parameter); 
  }
};

/***************************************/
template <typename TemplateType>
class MyClass
{

   template <typename ParameterTemplateType>
   void MyFunction(ParameterTemplateType myParameter)
   {
     // Do something; 
   }

   MyClass()
   {
      std::string parameter = L"Test String";

      // Do not know how to include the 
      // template<typename ParameterTemplateType> definition to bind call.
      // Storage::Functions.push_back(
      //     std::bind(&MyClass::MyFunction<ParameterTemplateType>,
//        this, std::placeholders::_1));

     // Or just something like:
     Storage::Function = std::bind(&MyClass::MyFunction<ParameterTemplateType>,
                             this, std::placeholders::_1));

      /***************************************/
      // Call the bound function with an explicit parameter somehow:
      std::string parameter = L"Test String";          
      Storage::Execute<std::string>(parameter);


   }
};

Answer 1:

关键的问题是,在C ++ 11你不能这样做:

// Doesn't compile
template <typename TemplateType>
static std::function<void(std::shared_ptr<TemplateType>)> Function;

类和函数可以被模板化,但不是成员属性。

“神奇”的是:

/*******************************************************************/
// Define a Function Pointer in a Container
class Storage
{
   template <typename TemplateType>
   struct FunctionContainer {
       static std::function<void(std::shared_ptr<TemplateType>)> Function;
   };
};
/*******************************************************************/
// Initialize FunctionContainer's Static Function Pointer if using static pointer.
template <typename TemplateType>
std::function<void(std::shared_ptr<TemplateType>)> Storage
    ::FunctionContainer<TemplateType>::Function;

然后,您可以绑定一个模板功能,该功能,如:

// Bind Function Pointer in Container to a Local Function
class MyClass
{
   template <typename TemplateType>
   void MyFunction(std::shared_ptr<TemplateType> parameter)
   {
     // Do something.
     // You can make this templated or non-templated.
   }
   MyClass()
   {
     // If you really want, you can templatize std::string in the following:
     Storage::FunctionContainer<std::string>::Function 
       = std::bind(&MyFunction<std::string>, this, std::placeholders::_1);
   }
}

你可以调用所有这一切,并提供了一个模板类型参数,如下所示:

//Invocation
std::shared_ptr<std::string> parameter;
parameter->get() = "Hello World".
Storage::FunctionContainer<std::string>::Function(parameter);


Answer 2:

为模板参数std::function应该是函数的签名模板类型替换已完成 。 在你的情况,既不TemplateType也不FunctionTemplateType对成员函数的签名效果MyFunction -它总是会返回一个std::string ,并采取单一std::string参数。 因此, std::function你会在你存储std::vector应该是:

static std::vector<std::function<std::string(std::string)>> Functions;

回想一下,一个成员函数具有一个隐含的第一个参数this 。 你需要的第一个参数绑定MyClass<...>::MyFunc<...>你希望它被叫做对象。 据推测,因为你在结合功能MyClass的构造函数,你希望对象是MyClass实例。 这意味着你push_back应该是这样的:

Storage::Functions.push_back(
  std::bind(&MyClass<TemplateType>::MyFunction<int>, this,
    std::placeholders::_1)
);

现在被推入函数Functions被绑定到MyClass对象,并采取类型的单个参数std::string 。 你可以调用这些函数,像这样之一:

Storage::Functions[0]("something");


Answer 3:

如果我理解你的权利... :)

因为模板的<class T>无效美孚(T)函数FOO <int>的()和Foo <双>是不同类型的,你不能创建矢量持有指向同时你想要做什么是不可能的,其功能直接原因载体是均质的容器。

为了克服我们可以使用boost ::变种<>要么存储指向不同类型的功能或者存储的功能参数。

template<class T> void foo(T);
typedef boost::variant<void (*)(int), void (*)(double)> func_ptr_variant;
std::vector<func_ptr_variant> v;
v.push_back(foo<int>);
v.push_back(foo<double>);

typedef boost::variant<int, double> argument;
std::vector<void (*)(argument)) v;
v.push_back(foo);
v.push_back(bar);
// foo and bar are defined as void foo(argument a) and void bar(argument a)

不幸的是,在任何情况下,你需要将它们插入到容器之前实例化函数模板,因为C ++不能在飞行做代码生成。 我认为这是可能的,你知道所有可能的类型的参数,该功能可让可能是没有问题的使用。



Answer 4:

MyClass的的C-TOR不知道任何有关FunctionTemplateType这就是为什么它的push_back唯一明确的专业 (抱歉,这是我的任期......我不知道正确的术语)这样的

#include <functional>
#include <vector>
#include <string>

struct Storage
{
  // Have no idea what this signature should really be:
  static std::vector<std::function<void ()>> Functions;

};
std::vector<std::function<void ()>> Storage::Functions;

template <typename TemplateType>
class MyClass
{
   template <typename FunctionTemplateType>
   std::string MyFunction(std::string myParameter)
   {
     return "Hellö: " + myParameter;

   }
public:
   MyClass()
   {
      Storage::Functions.push_back(
          std::bind( & MyClass<TemplateType>::MyFunction<std::string>, this, "borisbn" )
//                                                       ^^^^^^^^^^^
      );
   }
};

int main() {
    MyClass<int> obj;
}

liveworkspace链接



文章来源: C++ How to Reference Templated Functions using std::bind / std::function