Пакет параметров шаблона переменной C ++? [Дубликат]

Тип математики с плавающей запятой, которая может быть реализована на цифровом компьютере, обязательно использует приближение реальных чисел и операций над ними. (Стандартная версия стандартная работает до более чем пятидесяти страниц документации и имеет комитет для рассмотрения ее ошибок и дальнейшего уточнения.)

Это приближение представляет собой смесь приближений разного типа, каждый из которых можно либо игнорировать, либо тщательно учитывать из-за его конкретного способа отклонения от точности. Это также включает в себя ряд явных исключительных случаев как на уровне аппаратного обеспечения, так и на уровне программного обеспечения, которое большинство людей прогуливает прямо мимо, делая вид, что не замечает.

Если вам нужна бесконечная точность (например, вместо числа π одного из его более коротких резервных копий), вы должны написать или использовать символическую математическую программу.

Но если вы в порядке с идеей о том, что иногда математика с плавающей запятой нечеткая по значению и логике и ошибки могут быстро накапливаться, и вы можете написать свои требования и тесты для этого, тогда ваш код может часто проходить с помощью того, что находится в вашем FPU.

17
задан ForceBru 17 February 2016 в 13:34
поделиться

8 ответов

Шаблоны Variadic являются частью стандарта C ++ 0x, который еще официально не выпущен. Они поддерживаются gcc с версии 4.3, но вам нужно включить поддержку C ++ 0x, добавив компилятор -std = c ++ 0x.

2
ответ дан David Feurle 4 September 2018 в 10:18
поделиться

другой синтаксис: расширение, например

template<typename VAL, typename... KEYS>
class MyMaps
{
  typedef std::tuple< std::map<KEYS,VAL>... > Maps;
}

, следовательно:

MyMaps<int,int,string>:Maps

теперь фактически:

std::tuple<std::map<int,int>,std::map<string,int> >
0
ответ дан Erez 4 September 2018 в 10:18
поделиться

Это пример вариационных шаблонов, которые я выставил в своем блоге: http://thenewcpp.wordpress.com/2011/11/23/variadic-templates-part-1-2/

Он компилируется. Он демонстрирует поиск самого большого типа из группы типов.

#include <type_traits>

template <typename... Args>
struct find_biggest;

//the biggest of one thing is that one thing
template <typename First>
struct find_biggest<First>
{
  typedef First type;
};

//the biggest of everything in Args and First
template <typename First, typename... Args>
struct find_biggest<First, Args...>
{
  typedef typename find_biggest<Args...>::type next;
  typedef typename std::conditional
  <
    sizeof(First) >= sizeof(next),
    First,
    next
  >::type type;
};
4
ответ дан Jarryd 4 September 2018 в 10:18
поделиться

Одним из самых простых возможных примеров является следующая реализация max, которая даже не шаблонна для типов.

int maximum(int n)
{
    return n;
}

template<typename... Args>
int maximum(int n, Args... args)
{
    return max(n, maximum(args...));
}

Только немного сложнее каноническая реализация printf:

void printf(const char *s)
{
  while (*s)
  {
    if (*s == '%' && *(++s) != '%')
      throw "invalid format string: missing arguments";
    std::cout << *s++;
  }
}

template<typename T, typename... Args>
void printf(const char* s, T value, Args... args)
{
  while (*s)
  {
    if (*s == '%' && *(++s) != '%')
    {
      std::cout << value;
      printf(s, args...); // call even when *s == 0 to detect extra arguments
      return;
    }
    std::cout << *s++;
  }
  throw "extra arguments provided to printf";
}
23
ответ дан Motti 4 September 2018 в 10:18
поделиться

Очень простой пример вариационного шаблона:

Предположим, мы хотим иметь функцию, которая принимает переменное количество аргументов и печатает их все. Для ex:

print("Hello", 1, 3.14, 5L);

Для этой функциональности нам потребовались бы в основном две функции:

Первая, функция, которая принимает переменное число аргументов:

template<typename T, typename... Args>
void print(T t, Args ...args){
     std::cout << t << ", ";
     print(args...);
}

Некоторые объяснения:

1.) Пакеты параметров, обозначенные ellipsis (...), которые отображаются в списке параметров.

typename...Args 
        |  | << Optional whitespace. Can have multiple whitespaces in between them
    Args...args

Это означает, что все они одинаковы .

typename ...args
typename...args
typename   ...   args

Итак, вам не нужно беспокоиться о правильной позиции пробелов. Хотя в качестве наилучшей практики следует использовать ИМО не более одного пробела.

2.) Расширение пакета: шаблон, за которым следует многоточие.

print(args...); //expand when you wish to use them

3.) Пакет параметров принимает нулевые или более шаблонные аргументы. Таким образом, print(T t, Args... args) принимает один или несколько аргументов .


Как только вы это понимаете, мы можем визуализировать поток вызовов, как показано ниже:

print("Hello", 1, 3.14, 5L);

означает:

print(string, int, float, long);

, который вызывает

print(int, float, long);

, который вызывает

print(float, long);  // say Level 2

, который вызывает

print(long);         // say Level 1

, который вызывает

print();             // say Level 0

Если вы внимательно следили за точкой № 3, вы должны были понять, что print(T t, Args... args) не может обрабатывать вызов на уровне 0. Поэтому нам нужна другая функция здесь с тем же именем догоняйте на любом уровне> = 0.


Во-вторых, функция захватывает вызов в верхней части стека вызовов:

Catch на уровне 0:

void print(){}

или, Поймать на уровне 1:

template<typename T>
void print(T t){ std::cout << t;}

или, Поймать на уровне 2:

template<typename T, typename U>
void print(T t, U u){ std::cout << t << ", " << u;}

и так далее ...

Любое из них будет работать. Надеюсь, это поможет вам в следующий раз, когда вы начнете писать такую ​​функцию или класс.

2
ответ дан Saurav Sahu 4 September 2018 в 10:18
поделиться

Шаблоны Variadic - это функция C ++ 0x, которая в первую очередь нацелена на авторов общих библиотек. Я бы не ожидал увидеть их в «коде пользователя». Например, в стандартной библиотеке C ++ 0x они используются во многих местах: std :: function, std :: async, std :: reference_wrapper, std :: tuple, std :: packaged_task, ...

Чтобы дать вам пример, я покажу вам, как может быть реализована reference_wrapper в отношении вариационных шаблонов:

template<class T>
class reference_wrapper
{
    T *ptr;
public:
    explicit reference_wrapper(T& thing) : ptr(&thing) {}
    explicit reference_wrapper(T&&     ) = delete;

    operator T&() const {return *ptr;}

    template<class... Args>
    decltype( declval<T&>()(declval<Args>()...) )
    operator()(Args&&... args) const
    {
        return (*ptr)(forward<Args>(args)...);
    }
};

Это не совсем соответствует стандарту, но предполагается для компиляции с небольшими изменениями. Он демонстрирует несколько функций C ++ 0x:

  • удаленные функции (отключение конструктора для rvalues)
  • ссылки rvalue (обнаружение аргументов rvalue для конструктора, совершенная переадресация)
  • с помощью decltype
  • шаблона стандартной библиотечной функции declval для создания объектов с целью создания выражения для decltype (GCC пока не предлагает этот шаблон функции. необходимо записать это самостоятельно)
  • variadic templates (принимает произвольное количество параметров)

Цель шаблона вариационного элемента - переслать аргументы объекту, указанному в ptr. Это должно работать в случае, если T - тип указателя функции или тип класса с перегруженным оператором вызова функции.

cheers! с

11
ответ дан sellibitze 4 September 2018 в 10:18
поделиться

До C ++ 11 вы можете создать шаблон только с фиксированным количеством параметров.

Форматировать шаблон для функции с одним параметром.

Второй шаблон для функции с два параметра. ... ie

Так как C ++ 11 вы можете написать только один шаблон, компилятор будет генерировать нужную функцию.

Хороший пример http: //eli.thegreenplace. нетто / 2014 / VARIADIC-шаблоны-в-с /

0
ответ дан Sergey 4 September 2018 в 10:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: