Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Void f(Types . args);






f(); // OK: args не содержит аргументов

f(1); // OK: args содержит один аргумент: int

f(2, 1.0); // OK: args содержит 2 аргумента: int и double

 

Мы можем создать шаблонный тип с переменным числом аргументов:

template< typename Head, typename... Tail>

class tuple< Head, Tail...>

: private tuple< Tail...> {

// Используем рекурсию

// По сути, кортеж (tuple) содержит голову (первую пару (тип/значение)

// и наследует от кортежа с хвостом (остальные пары тип/значение).

// Обратите внимание, что тип зашит в типе, а не хранится в виде данных

typedef tuple< Tail...> inherited;

public:

tuple() { } // Значение по умолчанию: пустой кортеж

// Создаем кортеж по независимым аргументам:

tuple(typename add_const_reference< Head>:: type v,

typename add_const_reference< Tail>:: type... vtail)

: m_head(v), inherited(vtail...) { }

// Создаем кортеж по другому кортежу:

template< typename... VValues>

tuple(const tuple< VValues...> & other)

: m_head(other.head()), inherited(other.tail()) { }

template< typename... VValues>

tuple& operator=(const tuple< VValues...> & other) // присваивание

{

m_head = other.head();

tail() = other.tail();

return *this;

}

typename add_reference< Head>:: type head() { return m_head; }

typename add_reference< const Head>:: type head() const { return m_head; }

inherited& tail() { return *this; }

const inherited& tail() const { return *this; }

protected:

Head m_head;

}

 

С таким определением мы можем создавать кортежи (а также копировать и работать с ними):

tuple< string, vector, double> tt(" hello", {1, 2, 3, 4}, 1.2);

string h = tt.head(); // " hello"

tuple< vector< int>, double> t2 = tt.tail(); // {{1, 2, 3, 4}, 1.2};

 

Поскольку указывать все эти типы довольно утомительно, то обычно, мы можем вывести аргументы типов, например, с помощью метода стандартной библиотеки make_tuple():

// это несколько упрощенное определение (см. раздел стандарта 20.5.2.2)

template< class... Types>

tuple< Types...> make_tuple(Types& &... t)

{

return tuple< Types...> (t...);

}

string s = " Hello";

vector< int> v = {1, 22, 3, 4, 5};

auto x = make_tuple(s, v, 1.2);

 

См. также:

  • Standard 14.6.3 Variadic templates
  • [N2151==07-0011] D. Gregor, J. Jarvi: Variadic Templates for the C++0x Standard Library.
  • [N2080==06-0150] D. Gregor, J. Jarvi, G. Powell: Variadic Templates (Revision 3).
  • [N2087==06-0157] Douglas Gregor: A Brief Introduction to Variadic Templates.
  • [N2772==08-0282] L. Joly, R. Klarer: Variadic functions: Variadic templates or initializer lists? -- Revision 1.
  • [N2551==08-0061] Sylvain Pion: A variadic std:: min(T,...) for the C++ Standard Library (Revision 2).
  • Anthony Williams: An introduction to Variadic Templates in C++0x. DevX.com, May 2009.

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.