所以假设我有一个包含函数对象的类,并且在构造函数调用中我传递了参数,这些参数将在稍后传递给函数对象。类似的东西:
class Binder{
public:
Binder(functional_object, listOfParameters);
callFunctionalObject(); // calls functional object with given list of parameters
};
在C ++ 11之前,我无法使用Variadic模板,所以可以这样做:
struct none{};
template <typename T1, typename T2=none, typename T3=none>
class Binder{
public:
Binder(T1 functionalObject, T2 arg1=none(), T3arg3=none());
void callFunctionalObject();
private:
T1 m_functionalObject;
T2 m_arg1;
T3 m_arg2;
};
callFunctionalobject
可以按如下方式实施:
template<typename T1, typename T2, typename T3>
void Binder<T1,T2,T3>::callFunctionalObject(){
callImpl(m_functionalObject, m_arg1, m_arg2);
}
和callImpl
将被重载以识别类型none
的对象,以将适当数量的参数传递给功能对象。
现在切换到C ++ 11我不知道如何实现这个事实,在私有部分我有成员,我可以直接访问。
有人能解释我使用C ++ 11或C ++ 14的方式吗?
答案 0 :(得分:7)
您应该存储std::function
和std::tuple
,然后在元组上调用该函数。
这是一个有效的C ++ 14解决方案
#include <iostream>
#include <functional>
template<typename T1, typename ...T>
class Binder
{
public:
Binder(std::function<T1(T...)> f, std::tuple<T...> t) : m_functional_obj(f), m_parameters(t) {}
template<std::size_t ...I>
T1 callImpl(std::index_sequence<I...>)
{
return m_functional_obj(std::get<I>(m_parameters)...);
}
T1 callFunctionalObject()
{
return callImpl(std::index_sequence_for<T...>{});
}
private:
std::function<T1(T...)> m_functional_obj;
std::tuple<T...> m_parameters;
};
int test(int i)
{
std::cout << "test(" << i << ")" << std::endl;
return i + 1;
}
int main()
{
Binder<int,int> bibi(test, std::make_tuple<int>(2));
auto res = bibi.callFunctionalObject();
std::cout << "res is " << res << std::endl;
}
<强> Live code 强>
答案 1 :(得分:4)
我的例子:
// Indices
template <std::size_t... Is>
struct Indices {};
template <std::size_t N, std::size_t... Is>
struct BuildIndices : BuildIndices <N - 1, N - 1, Is...> {};
template <std::size_t... Is>
struct BuildIndices<0, Is...> : Indices < Is... > {};
template<class FuncObject, class ... T>
class Binder
{
public:
Binder(FuncObject funcObject, T... args)
: m_funcObject(funcObject), m_arguments(std::make_tuple(args...))
{
}
void Call()
{
DoCall(BuildIndices<sizeof ... (T)> {});
}
private:
template<size_t... Ind>
void DoCall(Indices<Ind...>)
{
return m_funcObject(std::get<Ind>(m_arguments)...);
}
FuncObject m_funcObject;
std::tuple<T...> m_arguments;
};
void Foo(int, char)
{
}
int main()
{
Binder<void(*)(int, char), int, char> f(Foo, 1, 'd');
f.Call();
return 0;
}
答案 2 :(得分:2)
最简单的方法是使用std::function
存储具有已设置参数的std::bind
对象:
class Binder{
public:
template <typename T1, typename... T2>
Binder(T1 functionalObject, T2... args) : f(std::bind(functionalObject, args...)) {}
void callFunctionalObject() { f(); }
private:
std::function<void()> f;
};
void foo(int n, std::string s) {
std::cout << n << " " << s << std::endl;
}
int main()
{
Binder b(foo, 42, "test");
b.callFunctionalObject();
}
如果您需要更高级的东西,那么您可能希望将函数参数存储在std::tuple
中,然后使用一些模板魔法来解包它,但请指出您在问题中究竟需要什么。
P.S。另请参阅"unpacking" a tuple to call a matching function pointer