Спецификация пакета параметров С++ в конструкторе, а не в шаблоне

В отличие от объявлений функций с пакетами параметров, я обнаружил, что классам требуется тип для каждого аргумента в угловых скобках...

Component<IntegerPair, int, int> temp(40, 5);

... что кажется излишним. Вот как я определил Component:

template<typename T, class... T_Args>
class Component
{
public:
  Component(T_Args... args)
    : m_data(args...)
  {}

  T m_data;
};
  1. Есть ли способ удалить int, int из приведенного выше утверждения?
  2. Если да, можно ли его удалить?
  3. Кроме того, мой способ создания экземпляра m_data безопасен? При использовании std::forward<T_Args>(args)... мой компилятор сказал мне, что у меня нет конструктора, который мог бы преобразовывать все типы аргументов.

person user3097902    schedule 19.07.2015    source источник
comment
Вы в основном спрашиваете, возможно ли вывести аргументы шаблона класса из вызова конструктора, на который ответ нет. Что вам понадобится, так это функция создателя, например, std::make_pair is, или шаблон конструктора.   -  person jrok    schedule 19.07.2015
comment
3: вам нужно использовать универсальную ссылку T_Args&&, чтобы использовать идеальную переадресацию   -  person tkausl    schedule 19.07.2015
comment
Релевантно: stackoverflow.com/questions/29677505/   -  person cpplearner    schedule 19.07.2015


Ответы (2)


Один из способов — сделать конструктор шаблоном:

#include <utility>

struct IntegerPair {
    IntegerPair(int, int) {}
};

template<typename T>
class Component
{
public:
  template<typename... T_Args>
  Component(T_Args&&... args)
    : m_data(std::forward<T_Args>(args)...)
  {}

  T m_data;
};

int main()
{
    Component<IntegerPair> c {1,2};
}

Это функционально эквивалентно std::vector и его функции-члену emplace_back. Это совершенно нормально, имхо. Сообщения об ошибках довольно загадочны, как обычно в подобных конструкциях шаблонов, но это можно смягчить с помощью соответствующего static_assert.

person jrok    schedule 19.07.2015
comment
Это именно то, что я искал, и вы также исправили переадресацию. Почему фигурные скобки для аргументов? - person user3097902; 19.07.2015
comment
@user3097902 user3097902 Без особой причины, это более новый синтаксис :) В этом случае круглые скобки будут эквивалентны. - person jrok; 19.07.2015

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

template<typename T, class... T_Args>
Component<T, T_Args...> makeComponent(T_Args&&... args) {
   return Component<T, T_Args...>(std::forward<T_Args>(args)...);
}

Использование:

auto c = makeComponent<IntegerPair>(1, 1)
person shoosh    schedule 19.07.2015