我似乎无法通过以下方式使用多层模板,
template <typename T>
template <T value>
void printValueAsInteger()
{
printf("value as integer is %i\n", (int) value);
}
所以它可以被称为:
printValueAsInteger<123>();
它会导致以下错误消息:too many template-parameter-lists
。
如果我使用template <typename T, T value>
with printValueAsInteger<int, 123>()
,它可以工作,但这需要我明确指定类型。我怎样才能让它printValueAsInteger<123>()
打印出来value as integer is 123
?
编辑:
我会更具体地说明我需要这个。我的目标是将成员函数作为函数指针传递,我想用模板包装它:
template <typename T>
template <T* instance, void (T::*method)()>
void wrappedMethod()
{
(instance->*method)();
}
void callFunction(void (*function)())
{
(*function)();
}
然后像这样传递它:
Base *instance = new Derived;
callFunction(&wrappedFunction<instance, Base::method>);
编辑:
呃,我刚刚意识到我可能不应该(也不能)使用运行时定义的变量作为模板参数。我现在正在尝试使用一个用其他模板参数实例化的类来解决它,并创建一个使用该类的模板函数。或类似的东西。不,不起作用。
请注意,我无法更改 callFunction 的签名,因为它是第三方 API 的一部分。
最后!
我将以下内容放在标题中,
class Callable
{
public:
virtual ~Callable() { }
virtual void call() { }
};
typedef void (*functionPtr)();
extern unsigned nextMethodId;
extern functionPtr wrappedMethods[];
extern Callable *boundMethods[];
template <unsigned I>
class MethodWrapper
{
public:
static void function();
};
template <typename T>
class Method : public Callable
{
public:
Method(T* instance, void (T::*method)());
virtual void call();
private:
T* instance;
void (T::*method)();
};
template <typename T>
Method<T>::Method(T* instance, void (T::*method)())
: instance(instance), method(method) {
}
template <typename T>
void Method<T>::call()
{
if (instance && method)
(instance->*method)();
}
template <typename T>
static functionPtr bindMethod(T* instance, void (T::*method)())
{
boundMethods[nextMethodId] = new Method<T>(instance, method);
return (void (*)()) wrappedMethods[nextMethodId++];
}
这在源文件中:
#include "<insert header name here>.h"
unsigned nextMethodId = 0;
functionPtr wrappedMethods[] = {
&MethodWrapper<0>::function,
&MethodWrapper<1>::function,
&MethodWrapper<2>::function
};
Callable *boundMethods[sizeof(wrappedMethods) / sizeof(functionPtr)];
template <unsigned I>
void MethodWrapper<I>::function()
{
boundMethods[I]->call();
}
我可以这样使用它:
Base *instance = new Derived;
void (*function)() = bindMethod(instance, &Base::method);
callFunction(function);
它成功调用了派生实例的方法版本。遗憾的是,允许绑定的方法数量是固定的(本例中为三个),但它很容易扩展。