Я пытаюсь использовать набор классов шаблонов с переменным параметром. У меня впереди несколько вариантов, из которых я мог бы выбрать. До того, как какой-либо из моих шаблонов будет объявлен или определен, у меня в настоящее время есть эти прототипы: я знаком с шаблонами, но у меня не было большого опыта работы с вариативными типами при работе с шаблонами, поэтому синтаксис иногда меня немного сбивает с толку. Поскольку все они являются пустыми оболочками, они в настоящее время компилируются.
template<typename ClassType, typename... Args> class MatrixReference;
template<typename ClassType, typename... Args> class MatrixStorage;
template<typename ClassType, typename... Args> class MatrixAllocation;
У меня есть пользовательский класс, который будет использовать эти классы в зависимости от целей использования; в настоящее время это пустая оболочка, пока я не получу другие классы, определенные правильно с соответствующим поведением:
template<typename ClassType, typename... Args>
class Matrix {
};
Остальная часть класса из прототипов, показанных выше, будет унаследована от базового класса, так что указанный выше пользовательский класс будет иметь их контейнер, такой, что контейнер будет: std::vector<std::unique_ptr<MatrixBase>>
или std::vector<shared_ptr<MatrixBase>>
, а вектор будет содержать только 1 каждого типа из перечисленные прототипы. Например, вектор [0] будет содержать MatrixStorage, вектор [1] будет содержать MatrixReference, а вектор [2] будет содержать MatrixAllocation. У каждого из этих классов разные обязанности, как следует из их названия. Класс хранения будет содержать необработанную копию стека элементов. Ссылочный класс будет использоваться для ссылки на эти копии. Класс распределения будет использоваться при объявлении элементов в куче. Базовый класс выглядит так:
template <typename ClassType = void>
class MatrixBase {
protected:
MatrixBase(){}
virtual ~MatrixBase(){}
}; // Matrix
Я также думал о наследовании их от не шаблонной базы, поскольку этот класс ничего не делает, кроме как для того, чтобы иметь возможность хранить различные типы классов в одном контейнере. Я могу пойти дальше и изменить его на тип, не являющийся шаблоном, но пока я использую его как есть, чтобы придерживаться соглашений его производных типов.
Теперь об объявлении моих шаблонов классов: мне действительно нужно использовать здесь только один из них, поскольку все они следуют одному шаблону, но я все равно покажу все 3, поскольку в настоящее время они являются пустыми оболочками.
// Stores All Of The Contents Of The Matrix
template<typename ClassType, typename... Args>
class MatrixStorage : public MatrixBase<ClassType> {
}; // MatrixStorage
// Used To Reference The Storage Class Of The Matrix
template<typename ClassType, typename... Args>
class MatrixReference : public MatrixBase<ClassType> {
}; // MatrixReference
// Used Only When User Wants To Create A Matrix On The Heap
template<typename ClassType, typename... Args>
class MatrixAllocation : public MatrixBase<ClassType> {
}; // MatrixAllocation
Подход к проектированию, который я ищу, заключается в том, что когда этот класс используется, он следует шаблону, где первый тип всегда является типом данных, которые матрица будет хранить, либо это будет int, float или какой-либо другой определяемый пользователем тип; следующий параметр - это то место, где используется переменный параметр, так что, если создается экземпляр шаблона как такового:
Matrix<float,2,2> mat2x2; // Default constructor making it empty
Это сгенерирует матрицу поплавков размером 2x2.
Matrix<int,3,3,3> mat3x3x3;
Это сгенерирует объемную матрицу целых чисел 3x3x3
Таким образом, часть вариативного шаблона всегда будет + целых чисел, а минимальное требование будет Matrix<type, 1>
, где это будет в некотором смысле скалярная или одноэлементная матрица или матрица 1x1.
Здесь мне предлагается несколько вариантов. Я мог бы использовать следующее
- size_t ... N
- беззнаковый ... D
- typename ... Args
В настоящий момент, как вы можете видеть, он объявлен с последним из вариантов. Итак, теперь возникает главный вопрос:
Если бы я решил использовать Parameter Pack, где у меня есть вспомогательный класс как таковой:
template <typename ClassType,typename... Dimensions>
class DimensionPack {
public:
typename std::tuple<ClassType, std::tuple<Dimensions...> >::type Dim;
const unsigned int numarguments = sizeof...(Dimensions);
};
Вопрос становится; есть ли известный способ сделать параметр Variadic одного и того же типа, а именно size_t
или unsigned int
? Если да, то пример будет оценен или ссылка на ссылку тоже поможет; Я искал и не нашел ничего полезного, достаточно похожего, чтобы помочь мне в этом.
Если нет, я не возражаю против использования size_t
или unsigned int
, но я предпочитал иметь возможность использовать вспомогательный шаблон для упаковки и распаковки вариативных параметров таким образом, что мне не нужно реализовывать это в каждом и каждый класс.
У меня также есть 2 других производных класса, которые здесь не показаны, но один будет использоваться для записи их на экран, а другой будет использоваться для чтения и синтаксического анализа из файла и записи в файл.
Также в качестве примечания: для чрезвычайно больших наборов данных или матриц чрезвычайно большого размера: у меня также есть этот вспомогательный класс, который можно использовать для них:
template<typename ClassType, std::size_t bufferSize>
class MatrixBuffer {
static std::vector<ClassType> matrixBuffer = std::vector<ClassType>().reserve( bufferSize );
};
Изменить
Я забыл добавить это к исходному вопросу, но сейчас добавляю его для большей ясности. Мне действительно нужно протестировать значение каждого вариативного параметра, чтобы увидеть, является ли оно нечетным или четным, и их результаты будут сохранены в векторе с размером количества параметров, хранящих 0 для четных или 1 для нечетных. Это одна из причин, по которой я склонялся к использованию пакета параметров, потому что я мог просто передать его вспомогательной функции, которая вернула бы обратно необходимый вектор.
template<typename ClassType, std::size_t... Args>
? - person Alex Zywicki   schedule 02.02.2017std::size_t...
сохранять их в пакете параметров, необходимо также создать вектор размера этого пакета и заполнить его 0 для четных или 1 для нечетных. Я могу продолжить и добавить ясность к своему вопросу. - person Francis Cugler   schedule 02.02.2017size_t...Args
. Вы идете по ложному пути. - person Yakk - Adam Nevraumont   schedule 02.02.2017size_t...
, но что касается моего вспомогательного класса, вместо сохранения в кортеж; В итоге я инициализировалstd::vector<>
значениями пакета параметров. - person Francis Cugler   schedule 03.02.2017