Предложенное Джеймсом решение очень приятное!
Однако, если существует реальная потребность в частичной специализации, как это первоначально запрашивалось в вопросе (например, для реализации другого поведения в двух разных случаях), опираясь на ответ Джеймса Я бы предложил:
#include <iostream>
struct DynamicSize {};
template<int Size>
struct FixedSize {};
template<class T, class Size>
class Container;
template<class T, int size>
class Container<T, FixedSize<size>> {
public:
Container() { std::cout << "FixedSize: " << size << "\n"; }
};
template<class T>
class Container<T, DynamicSize> {
public:
Container() { std::cout << "dynamic size\n"; }
};
// you can also do that
template<class T>
class Container<T, FixedSize<0>> {
public:
Container() { std::cout << "Special case of FixedSize 0\n"; }
};
int main() {
Container<char, FixedSize<20>> a;
Container<char, DynamicSize> b;
Container<char, FixedSize<0>> c;
}
Пример вывода
FixedSize: 20
dynamic size
Special case of FixedSize 0
Но зачем останавливаться здесь?
Если есть необходимость специализироваться на самом размере (т. е. создать различную реализацию для разных значений фиксированного размера путем выбора предопределенного диапазона), можно сделать следующее:
enum class SIZE_RANGE {SMALL, MEDIUM = 10, BIG = 100};
constexpr bool operator<(int size, SIZE_RANGE s) {
return size < (int)s;
}
//------------------------------------------------------------------------------------
// FixedSize manages its own range selection here
template<int Size,
SIZE_RANGE SizeRange = (Size < SIZE_RANGE::MEDIUM? SIZE_RANGE::SMALL :
Size < SIZE_RANGE::BIG? SIZE_RANGE::MEDIUM :
SIZE_RANGE::BIG)>
struct FixedSize {};
//------------------------------------------------------------------------------------
Теперь мы можем специализироваться на размере Контейнера в соответствии с его диапазоном:
template<class T, class Size>
class Container;
template<class T>
class Container<T, FixedSize<0>> {
public:
Container() { std::cout << "Special case of FixedSize 0\n"; }
};
template<class T, int size>
class Container<T, FixedSize<size, SIZE_RANGE::SMALL>> {
public:
Container() { std::cout << "Small FixedSize: " << size << "\n"; }
};
template<class T, int size>
class Container<T, FixedSize<size, SIZE_RANGE::MEDIUM>> {
public:
Container() { std::cout << "Medium FixedSize: " << size << "\n"; }
};
template<class T, int size>
class Container<T, FixedSize<size, SIZE_RANGE::BIG>> {
public:
Container() { std::cout << "Big FixedSize: " << size << "\n"; }
};
template<class T>
class Container<T, DynamicSize> {
public:
Container() { std::cout << "dynamic size\n"; }
};
Что может быть продемонстрировано следующими основными:
int main() {
Container<char, DynamicSize> a;
Container<char, FixedSize<0>> b;
Container<char, FixedSize<5>> c;
Container<char, FixedSize<42>> d;
Container<char, FixedSize<100>> e;
}
Пример вывода
dynamic size
Special case of FixedSize 0
Small FixedSize: 5
Medium FixedSize: 42
Big FixedSize: 100
Живой пример
person
Amir Kirsh
schedule
04.06.2016