Variadic шаблоны - PullRequest
       32

Variadic шаблоны

23 голосов
/ 09 ноября 2008

C ++ 0x позволит шаблону принимать произвольное количество аргументов. Как лучше всего использовать эту функцию, кроме реализации кортежей?

Ответы [ 8 ]

33 голосов
/ 10 ноября 2008
  1. Тип безопасной печатиf
  2. Пересылка произвольного множества аргументов конструктора в фабричных методах
  3. Наличие произвольных базовых классов позволяет устанавливать и удалять полезные политики .
  4. Инициализация путем перемещения разнородных типизированных объектов непосредственно в контейнер с помощью конструктора variadic template'd.
  5. Наличие оператора литерал , который может вычислить значение для пользовательского литерала (например, "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; }

См. Пример кода: здесь

3 голосов
/ 20 августа 2012

Возможно, вас заинтересует выступление Андрея Александреску на мероприятии Going Native 2012:

Здесь - это видео, а Здесь - документация.

2 голосов
/ 04 сентября 2011

Я только что написал статью о том, как реализовать несколько COM-интерфейсов и сделать ваш код компактным и элегантным с помощью вариабельных шаблонов C ++ 0x.

2 голосов
/ 09 ноября 2008

Разрешение таким вещам, как Boost.Function принимать произвольные числа параметров

2 голосов
/ 09 ноября 2008
  • Тип безопасной printf
1 голос
/ 20 августа 2012

Я реализовал 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 класса с конструктором, который принимает два целых числа, я могу написать следующий код:

AbstractObject object = ConcreteObject(42, 42);

Это похоже на C # и Java (но с RAII), и оно работает для меня в C ++ / GCC 4.8 =)

0 голосов
/ 12 февраля 2016

Типобезопасный printf упоминался в других ответах, но в более широком смысле шаблоны с переменным числом аргументов можно использовать для реализации функций форматирования, которые вообще не требуют передачи информации о типе через спецификаторы формата. Например, библиотека C ++ Format реализует функции форматирования, подобные str.format :

в Python
fmt::print("I'd rather be {1} than {0}.", "right", "happy");

в дополнение к безопасной печати. Типы аргументов захватываются автоматически с использованием шаблонов с переменными числами в C ++ 11.

Это делает ненужными спецификаторы printf, такие как lld или пресловутый PRIdPTR, вместо

std::printf("Local number: %" PRIdPTR "\n\n", someIntPtr);

можно просто использовать

fmt::printf("Local number: %d\n\n", someIntPtr);

Отказ от ответственности : я являюсь автором этой библиотеки

0 голосов
/ 25 мая 2012

Введите безопасность каждого вызова с динамическим номером аргумента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...