如果你有一个模板类或模板函数(或两者的组合),你怎么绑定该功能,(保留模板类型参数)?
我给出关于以下职位基本语法一些帮助,结合显式模板类型参数的功能,但失去了在这个过程中提供的模板类型参数的能力。
是否有可能得到这个工作,所以它仍然可以提供模板类型参数与未来的呼叫?
清理这个代码很多,但它显然不能编译,因为我无法找到正确的语法,(有没有这样做的任何方式)?
去掉了“矢量”的要求,以简化这个:
谢谢您的帮助!
#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