次のように複数のテンプレートを使用することはできないようです。
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);
メソッドの派生インスタンスのバージョンが正常に呼び出されます。残念ながら、バインドできるメソッドの数は固定されています (この例では 3 つ) が、簡単に拡張できます。