2013-02-20 2 views
0

Я пытаюсь сделать что-то, что кажется простым, используя шаблоны, но я просто не могу заставить его работать. Класс реализует различные последовательные реализации ввода-вывода для AVR-процессора, но проблема - общая проблема на C++. Цель состоит в том, чтобы сделать опции во время компиляции на основе параметров шаблона для удобства пользователя и повышенного использования кода, а также улучшить производительность в некоторых местах из-за повторного использования.C++ Шаблон частичной специализации класса с функцией специализации

Проблема проста, но решение (если есть) я не могу найти. При компиляции кода, который следует с помощью Visual Studio 2008 я получаю:

error C2039: 't1' : is not a member of 'Interface<T1,0,_C> 
error C2039: 't1' : is not a member of 'Interface<T1,1,_C> 
error C2039: 't2' : is not a member of 'Interface<T2,0,_C> 
error C2039: 't2' : is not a member of 'Interface<T2,1,_C> 

** Я разделить мой тестовый код вверх в пояснительных куски, положить их все вместе в течение всего теста **

Это «родовой» шаблон база:

enum eType { T1, T2 }; 
enum eT1 { T1_I1, T1_I2 }; 
enum eT2 { T2_I1, T2_I2 }; 

//This defines the 'global/default' interface that is required 
template< eType _T, int _I, typename _C> 
struct Interface 
{ 
    bool initialise(); 
}; 

для этого я частично специализировать шаблон на основе параметра _t для добавления переменных-членов, которые используются инициализировать() и т.д.:

//t1 has a new member function which initialise() uses 
template< int _I, typename _C> 
struct Interface< T1, _I, _C > 
{ 
    bool initialise(); 
    void t1(); 
}; 

//t2 has a new member function which initialise() might uses 
template< int _I, typename _C> 
struct Interface< T2, _I, _C > 
{ 
    bool initialise(); 
    void t2(); 
}; 

//We can implement a function for T1 type 
template< int _I, typename _C> 
bool Interface< T1, _I, _C >::initialise() 
{ printf("T1 initialise\n"); return true; } 

//We can implement a function for T2 type 
template< int _I, typename _C> 
bool Interface< T2, _I, _C >::initialise() 
{ printf("T2 initialise\n"); return true; } 

//We can implement a function for T1 special function 
template< int _I, typename _C> 
void Interface< T1, _I, _C >::t1() 
{ printf("T1\n"); } 

//We can implement a function for T2 special function 
template< int _I, typename _C> 
void Interface< T2, _I, _C >::t2() 
{ printf("T2\n"); } 

Теперь на бит, который я не могу решить, как узнать, где я хочу специализироваться на реализации функций t1() и t2() на основе второго параметра шаблона _I.

//################ ISUE BELOW ################### 

//ERROR: We can't implement the special function for T1 based on _I specialization 
template< typename _C> 
void Interface< T1, (int)T1_I1, _C >::t1() 
{ printf("T1_I1 Special function\n"); } 

//ERROR: We can't implement the special function for T1 based on _I specialization 
template< typename _C> 
void Interface< T1, (int)T1_I2, _C >::t1() 
{ printf("T1_I2 Special function\n"); } 

//ERROR: We can't implement the special function for T2 based on _I specialization 
template< typename _C> 
void Interface< T2, (int)T2_I1, _C >::t2() 
{ printf("T2_I1 Special function\n"); } 

//ERROR: We can't implement the special function for T2 based on _I specialization 
template< typename _C> 
void Interface< T2, (int)T2_I2, _C >::t2() 
{ printf("T2_I2 Special function\n"); } 

//################ ISUE END ################### 

Теперь основной() функцию, которая проверяет все компилирует:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    struct Config {}; 
    Interface<T1, T1_I1, Config> t1i1; 
    Interface<T1, T1_I2, Config> t1i2; 
    Interface<T2, T2_I1, Config> t2i1; 
    Interface<T2, T2_I2, Config> t2i2; 

    t1i1.initialise(); 
    t1i2.initialise(); 
    t1i1.t1(); 
    t1i2.t1(); 

    t2i1.initialise(); 
    t2i2.initialise(); 
    t2i1.t2(); 
    t2i2.t2(); 
    return 0; 
} 

Проблема, как представляется, вызваны компилятором не видя существование первоначального класса специализации и использует не специализированный интерфейс, который не имеет t1() или t2(). Где я получил синтаксис здесь неправильно или есть простой хак/работа вокруг, чтобы выполнить то, что я пытаюсь сделать. Пока решение может привести к типу в форме Serial<UART,Hardware,Config> io, он соответствует моей цели!

+0

Вы не можете сделать это. Шаблоны функций не могут быть специализированы частично. –

ответ

0

Вы должны указать все частичные класс специализация один за другим. Пример:

template <eType E, int I, typename T> struct Interface; 

template <int I, typename T> struct Interface<T1, I, T> 
{ 
    void t1() { /* ... */ } 
    bool initialize() { /* ... */ } 
}; 

template <typename T> struct Interface<T1, static_cast<int>(T1), T> 
{ 
    void t1() { /* ... */ } 
    bool initialize() { /* ... */ } 
}; 

Вы всегда можете указать код, чтобы избежать повторения, когда это необходимо. Например:

namespace detail 
{ 
    template <typename T, int I> struct T1Helper 
    { 
     static bool initialize() { /* ... */ } 
    }; 
} 

// ... primary template as above ... 

template <int I, typename T> struct Interface<T1, I, T> 
{ 
    void t1() { /* ... */ } 
    bool initialize() { return detail::T1Helper<T, I>::initialize(); } 
}; 

// etc. 

Или вы могли бы учитывать общий код в подмешать шаблона:

template <int I, typename T> 
struct Interface<T1, I, T> : Mixin<T, I> 
{ 
    void t1() { /* ... */ } 
}; 
+0

Спасибо за ваш ответ. Я вижу, что нет возможности получить специализацию по частичным функциям, и ваши три примера очень полезны для демонстрации того, как обойти это. Я попробую версию MixIn, где он является Помощником, у которого hopefulyl будет все необходимые функции. В очередной раз благодарим за помощь. – Crog

Смежные вопросы