C++ Can';t通过";变量“;基于变量的模板
我已经编写了一些代码,用于存储一些带有参数的任务,以便以后执行。代码:C++ Can';t通过";变量“;基于变量的模板,c++,c++11,templates,variadic-templates,variadic-functions,C++,C++11,Templates,Variadic Templates,Variadic Functions,我已经编写了一些代码,用于存储一些带有参数的任务,以便以后执行。代码: class TaskInterface { public: virtual void Execute() = 0; }; namespace TaskHelper { template <std::size_t... Types> struct index {}; template <std::size_t N, std::size_t... Types>
class TaskInterface
{
public:
virtual void Execute() = 0;
};
namespace TaskHelper
{
template <std::size_t... Types>
struct index {};
template <std::size_t N, std::size_t... Types>
struct gen_seq : gen_seq<N - 1, N - 1, Types...> {};
template <std::size_t... Types>
struct gen_seq<0, Types...> : index<Types...>{};
}
template <typename ReturnType, typename... Types>
class SimpleTask : public TaskInterface
{
public:
template <typename Function>
SimpleTask(Function&& func, Types&&... args)
: m_function(std::forward<Function>(func)),
m_args(std::make_tuple(std::forward<Types>(args)...)) {
}
void Execute() override final
{
func(m_args);
}
private:
std::function<ReturnType(Types...)> m_function;
std::tuple<Types...> m_args;
template <typename... Args, std::size_t... Is>
void func(std::tuple<Args...>& tup, TaskHelper::index<Is...>)
{
m_function(std::get<Is>(tup)...);
}
template <typename... Args>
void func(std::tuple<Args...>& tup)
{
func(tup, TaskHelper::gen_seq<sizeof...(Args)>{});
}
};
template < typename ReturnType, class Class, typename... Types>
class MemberTask : public TaskInterface
{
public:
typedef ReturnType(Class::*Method)(Types...);
MemberTask(Class* object, Method method, Types&&... args) :
m_object(object), m_method(method), m_args(std::make_tuple(std::forward<Types>(args)...)) {
};
void Execute() override final
{
func(m_args);
};
private:
Class* m_object;
Method m_method;
std::tuple<Types...> m_args;
template <typename... Args, std::size_t... Is>
void func(std::tuple<Args...>& tup, TaskHelper::index<Is...>)
{
(m_object->*m_method)(std::get<Is>(tup)...);
}
template <typename... Args>
void func(std::tuple<Args...>& tup)
{
func(tup, TaskHelper::gen_seq<sizeof...(Args)>{});
}
};
template <typename Function, typename... Arguments>
TaskInterface* CreateSimpleTask(Function&& func, Arguments&&... args)
{
return new SimpleTask<typename std::result_of<decltype(func)(Arguments...)>::type, Arguments...>(std::forward<Function>(func), std::forward<Arguments>(args)...);
}
template <class Class, typename Method, typename... Arguments>
TaskInterface* CreateMemberTask(Class* obj, Method method, Arguments&&... args)
{
return new MemberTask<typename std::result_of<decltype(method)(Class)>::type, Class, Arguments...>(std::forward<Class*>(obj), std::forward<Method>(method), std::forward<Arguments>(args)...);
}
class Test {
public:
Test() { id = ++m_id; }
bool doIt(int n) {
std::cout << "doIt of " << n * id;
return true;
};
private:
static int m_id;
int id;
};
int Test::m_id = 0;
double test1(int xs)
{
xs *= 555;
return 66.02l;
}
而且不能以这种方式:
// error C2664: 'double (int)' : cannot convert argument 1 from 'int *' to 'int'
int xxxx;
TaskBase* st = CreateSimpleTask(test1, &xxxx);
或对于MemberTask:
// cannot convert argument 2 from 'bool (__thiscall Test::* )(std::string)' to 'bool (__thiscall Test::* )(std::string &)'
std::string ss = "sdfsdf";
TaskBase* mt = CreateMemberTask(&t, &Test::doIt, ss);
如何修改类,以便不仅通过“值”传递参数,而且通过“变量”传递参数?或者我所有的“体系结构”在这方面都是完全错误的?一种比存储具有特定签名及其参数的函数更简单的方法,就是存储没有参数的函数及其上下文(有时称为thunk)
std::函数st=[]{test1(5);};
函数mt=[&]{t.doIt(ss);};
这比你的代码简单得多,而且不会泄漏内存。您可以通过值、引用或组合来捕获上下文。lambda很酷 您可能应该在这里使用
std::bind
或lambda,如果您想存储它们,它将使您的代码更简单。实际的行和完整错误非常有用。如果您不理解错误,编辑它们是一个坏主意。您可能需要查看对应的错误。传递“变量”不是一个标准术语。我想你的意思是通过指针或引用传递。
// cannot convert argument 2 from 'bool (__thiscall Test::* )(std::string)' to 'bool (__thiscall Test::* )(std::string &)'
std::string ss = "sdfsdf";
TaskBase* mt = CreateMemberTask(&t, &Test::doIt, ss);
std::function<void()> st = [] { test1(5); };
std::function<void()> mt = [&] { t.doIt(ss); };