Я пытаюсь написать динамический диспетчер для функции, шаблонной для целых значений (не для типов). Хотя я мог либо написать генератор кода, либо использовать большую цепочку макросов для создания источника диспетчера, похоже, что шаблонное решение будет более элегантным.частная спецификация шаблона для динамической отправки
Я урезанная мой диспетчеру простой формы (которая на самом деле не делать какую-либо диспетчеризации):
// works fine with full template specialization
template <int N>
struct TestDispatcher1D {
int f(int n) {
if (n == N) return n; // replace me with actual dispatch
TestDispatcher1D<N-1> t;
return t.f(n);
}
};
template<>
struct TestDispatcher1D<-1> {
int f(int n) { return -1; }
};
// partial template specialization is problematic
template <int M, int N>
struct TestDispatcher2D {
int f(int m, int n);
};
template<int M>
struct TestDispatcher2D<M,-1> {
int f(int m, int n) { return -1; }
};
template<int N>
struct TestDispatcher2D<-1,N> {
int f(int m, int n) { return -1; }
};
template<>
struct TestDispatcher2D<-1,-1> {
int f(int m, int n) { return -1; }
};
template <int M, int N>
int TestDispatcher2D<M,N>::f(int m, int n) {
if ((n == N) && (m == M)) return n + m; // replace me with actual dispatch
if (m < M) {
if (n < N) {
TestDispatcher2D<M-1,N-1> t;
return t(m,n);
} else {
TestDispatcher2D<M-1,N> t;
return t(m,n);
}
} else {
TestDispatcher2D<M,N-1> t;
return t(m,n);
}
}
// test code
void testIt() {
{
TestDispatcher1D<16> t;
t.f(16);
}
{
TestDispatcher1D<16>t;
t.f(0);
}
{
TestDispatcher2D<16,16>t;
t.f(8,8);
}
}
При компиляции на GCC 4.1.1, я получаю следующие ошибки:
t.cpp: In member function 'int TestDispatcher2D::f(int, int) [with int M = 16, int N = 16]': t.cpp:63: instantiated from here t.cpp:40: error: no match for call to '(TestDispatcher2D) (int&, int&)' t.cpp:63: instantiated from here t.cpp:43: error: no match for call to '(TestDispatcher2D) (int&, int&)' t.cpp:63: instantiated from here t.cpp:47: error: no match for call to '(TestDispatcher2D) (int&, int&)'
По-видимому, когда я пытаюсь создать рекурсивные объекты, компилятор не рассматривает это как запрос на создание нового шаблона.
Любые предложения?
Вы также можете написать TestDispatcher2D <...>() .f (mn, n) –
Вот и все. Благодарю. Раньше я пытался использовать некоторые трюки operator() и пропустил это исправление. –
Вы можете даже сделать f статическим, поэтому вам вообще не нужно создавать временный объект. – sth