С++ 0x позволит шаблону принимать произвольное количество аргументов. Каково наилучшее использование этой функции, кроме реализации кортежей?
Шаблоны Variadic
Ответ 1
- Безопасный тип печати
- Переадресация произвольных аргументов конструктора в factory методах
- Наличие произвольных базовых классов позволяет устанавливать и удалять полезные политики.
- Инициализация путем перемещения гетерогенных типизированных объектов непосредственно в контейнер с помощью конструктора varadical template.d.
- Наличие литерал-оператора, который может вычислять значение для заданного пользователем литерала (например, "10110b" ).
Пример 3:
template<typename... T> struct flexible : T... { flexible(): T()... { } };
Пример 4:
struct my_container { template<typename... T> my_container(T&&... t) { } };
my_container c = { a, b, c };
Пример 5:
template<char... digits>
int operator "" b() { return convert<digits...>::value; }
Смотрите этот пример кода: здесь
Ответ 2
Возможно, разговор Андрея Александреску о событии Going Native 2012 будет интересен:
Ответ 3
- Типовой
printf
Ответ 4
Разрешая такие вещи, как Boost.Function, принимать произвольное количество параметров
Ответ 5
Я написал статью о том, как реализовать несколько COM-интерфейсов и сохранить ваш код компактным и элегантным с С++ 0x variadic templates.
Ответ 6
Я реализовал NDArray (N-мерный массив) и имеет метод setSizes с переменным количеством аргументов. Использование переменных аргументов шаблона является более безопасным, чем использование аргументов вариационной функции, более того, я могу контролировать количество параметров, переданных этой функции во время компиляции, только с переменными аргументами шаблона.
void setSizes(uintmax_t currentSize) {
static_assert(1 == NDimensions, "Invalid count of arguments given to setSizes.");
size_ = currentSize;
data_ = new NDArrayReferenceType[currentSize];
}
template <typename... Sizes>
void setSizes(uintmax_t currentSize, Sizes... sizes) {
static_assert(sizeof...(Sizes) + 1 == NDimensions, "Invalid count of arguments given to setSizes.");
size_ = currentSize;
data_ = new NDArrayReferenceType[currentSize];
for (uintmax_t i = 0; i < currentSize; i++) {
data_[i]->setSizes(sizes...);
}
}
Я также применил универсальную оболочку конструктора для собственного самодельного SmartPointer. Он охватывает весь пользовательский конструктор типа необработанного указателя.
template <typename TSmartPointer, typename... Args>
static inline void initialize(TSmartPointer *smartPointer, Args... args) {
smartPointer->pointer_ = new typename TSmartPointer::PointerType(std::forward<Args>(args)...);
smartPointer->__retain();
}
Этот код кажется неочевидным, это часть инициализатора SmartPointer для случая, должен ли SmartPointer автоматически вызывать конструктор указателя при приобретении SmartPointer (RAII). В случае абстрактных классов он не может вызвать конструктор.
Итак, если у меня есть тип AbstractObject, который является SmartPointer абстрактного класса, и тип ConcreteObject, который является SmartPointer класса с конструктором, который принимает два ints, я могу написать следующий код:
AbstractObject object = ConcreteObject(42, 42);
Это похоже на С# и Java (но с RAII), и он работает для меня в С++/GCC 4.8 =)
Ответ 7
Введите безопасность каждого вызова с динамическим номером аргумента.
Ответ 8
В других ответах упоминается безопасный тип printf, но более общие вариационные шаблоны могут использоваться для реализации функций форматирования, которые не требуют передачи информации о типе через спецификаторы формата. Например, библиотека формата С++ реализует функции форматирования, подобные Python str.format:
fmt::print("I'd rather be {1} than {0}.", "right", "happy");
в дополнение к безопасной печати. Типы аргументов записываются автоматически с использованием вариационных шаблонов в С++ 11.
Это делает ненужными спецификаторы printf, такие как lld
или пресловутый PRIdPTR
, а вместо
std::printf("Local number: %" PRIdPTR "\n\n", someIntPtr);
можно просто использовать
fmt::printf("Local number: %d\n\n", someIntPtr);
Отказ от ответственности. Я являюсь автором этой библиотеки