#c #c 11 #templates
#c #c 11 #шаблоны
Вопрос:
У меня есть шаблонный класс, который работает как таковой:
template <typename T, std::size_t maxSize>
class Foo
{
std::array<T, maxSize> arr;
};
Я хотел бы создать перегрузку, в которой вы можете выбрать только передачу T и вместо этого получить вектор в качестве базового контейнера:
template <typename T>
class Foo
{
std::vector<T> arr;
};
Как правильно это сделать?
Комментарии:
1. Вы бы согласились с созданием
maxSize
int
, вместоsize_t
?2. Да, это было бы хорошо.
3. Вы бы согласились с одним классом, который содержит соответствующий элемент, в зависимости от того, указан ли второй параметр шаблона?
4. Было бы приемлемо
Foo<T,0>
использоватьvector
вместоarray
? Массив нулевой длины не очень полезен, но я бы не стал считать «бесполезным», если вы не согласны. Более общий вопрос: есть ли какое-либо значениеmaxSize
, которое разумно можно использовать для обозначения «использовать вектор» вместо указания размера массива?
Ответ №1:
Вы можете использовать пакет параметров для размера и специализироваться на 1 аргументе или 0 аргументах:
Сначала укажите значение по умолчанию, при котором не удается скомпилировать
template <typename T>
struct always_false : std::false_type {};
template <typename T, std::size_t... Is>
class Foo {
static_assert(always_false<T>::value, "too many sizes");
};
Затем частично специализируйтесь на одном или нулевом аргументе:
template <typename T, std::size_t maxSize>
class Foo<T, maxSize> {
public:
std::array<T, maxSize> arr;
};
template <typename T>
class Foo<T>
{
public:
std::vector<T> arr;
};
Демонстрация: https://godbolt.org/z/5bW9c7
Комментарии:
1. Плюс этого в том, что позже, когда вам понадобится двумерный массив, он просто работает.
2. Очень приятно. Вы можете упростить это еще больше, просто не определяя первичный. ДЕМОНСТРАЦИЯ . Кроме того, в будущем нет необходимости удалять один ответ и публиковать другой, вы можете отредактировать другой.
3. Более лаконичный и простой код, верно, но использование статического утверждения, как показано, выдает более приятное сообщение об ошибке при сбое. Буду иметь в виду другие советы, спасибо.
4. Хорошо, достаточно справедливо 🙂 Хорошее решение.