2009-02-18 4 views
2

Я пытаюсь написать динамический диспетчер для функции, шаблонной для целых значений (не для типов). Хотя я мог либо написать генератор кода, либо использовать большую цепочку макросов для создания источника диспетчера, похоже, что шаблонное решение будет более элегантным.частная спецификация шаблона для динамической отправки

Я урезанная мой диспетчеру простой формы (которая на самом деле не делать какую-либо диспетчеризации):

// 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&)' 

По-видимому, когда я пытаюсь создать рекурсивные объекты, компилятор не рассматривает это как запрос на создание нового шаблона.

Любые предложения?

ответ

1

Вы просто не вызывая f() функцию в вашем рекурсивном вызове, вы пытаетесь «вызвать объект»:

Вы пишете:

TestDispatcher2D<...> t; 
return t(m,n); 

Но вы хотите:

TestDispatcher2D<...> t; 
return t.f(m,n); 
+0

Вы также можете написать TestDispatcher2D <...>() .f (mn, n) –

+0

Вот и все. Благодарю. Раньше я пытался использовать некоторые трюки operator() и пропустил это исправление. –

+0

Вы можете даже сделать f статическим, поэтому вам вообще не нужно создавать временный объект. – sth