У меня есть набор специализированных шаблонов. Теперь я хочу создать специализированные шаблоны для двух случаев:
Если в классе / структуре присутствует определенный метод (достаточно определения имени).
Если присутствует определенная свободная функция (в этом случае должны быть обнаружены имя и часть подписи).
Проблема в том, что и свободная функция, и метод класса будут также шаблонизированы. Это для своего рода архитектуры сериализации, и у меня есть несколько способов сериализации, поэтому параметром шаблона для метода / функции будет стратегия сериализации, предоставляемая другим специализированным шаблоном. Я не могу сделать стратегию абстрактной базой, потому что позже будут вызваны другие шаблонные методы, а виртуальные и шаблоны не будут смешиваться.
Вот пример того, что мне нужно:
template<typename T>
struct strategy1 {};
template<>
struct strategy1<char> {
void call() {
// Do char specific stuff
}
};
class foo_specialized {
/* ... */
};
template<>
struct strategy1<foo_specialized> {
void call() {
// do foo_specialized stuff
}
};
class foo_method {
public:
template< Typename T>
void serialize( T & t ) {
// use T here to do stuff
}
};
/* This should be used for foo_method */
template< typename T >
struct strategy1</* don't know what to put here */>
struct strategy1_helper{
template<typename T2>
void call( T2 t ) {
// do stuff with t
}
};
void call( const T & t ) {
t.serialize( strategy1_helper() );
}
};
class foo_function {
/* ... */
};
template<typename T>
void serialize( const foo_function & foo, T & t ) {
// use T here
}
/* This should be used for foo_function */
template< typename T >
struct strategy1</* don't know what to put here */>
struct strategy1_helper{
template<typename T2>
void call( T2 t ) {
// do stuff with t
}
};
void call( const T & t ) {
serialize( t, strategy1_helper() );
}
};
Можно ли каким-то образом заставить механизм разрешения шаблонов выбирать эти две последние специализации на основе фактического предоставленного аргумента? Или есть более чистый дизайн, чтобы достигнуть этого?
Я могу легко использовать черты типа и средства метапрограммирования, предоставляемые C ++ 11, поэтому мне не нужно выполнять шаги SFINAE самостоятельно.