std :: forward не может преобразовать заключенный в скобки список инициализаторов - PullRequest
0 голосов
/ 07 ноября 2018

Почему экран структуры struct не может правильно инициализировать структуру кадра?

Я хочу инициализировать структуру экрана и напрямую инициализировать также 2 структуры кадра.

#include <iostream>
#include <sstream>
#include <cstring>

#define ESC "\033"

struct frame {
  public:
    frame(unsigned int w, unsigned int h) :
      m_w(w),
      m_h(h) {}

  private:
    unsigned int m_w, m_h;
};

struct screen {
  public:
    template<typename ... Args>
      screen(Args && ... args0, Args && ... args1) :
        m_f0(std::forward<Args>(args0)...),
        m_f1(std::forward<Args>(args1)...) {}

  private:
    frame m_f0, m_f1;
};

int main() {
  frame f = {16, 16};

  screen s = {f, {16, 16}};

  return 0;
}

1 Ответ

0 голосов
/ 07 ноября 2018

{16, 16} не имеет типа. Если он используется в контексте для инициализации чего-либо с типом, он инициализирует эту вещь.

Аргументы конструктора имеют тип. Выведенные аргументы конструктора шаблона получают свой тип от переданного аргумента. Но {16,16} не имеет типа, поэтому он не может вывести тип из того, что не имеет типа.

Ваша вторая проблема заключается в следующем:

  template<typename ... Args>
  screen(Args && ... args0, Args && ... args1) :
    m_f0(std::forward<Args>(args0)...),
    m_f1(std::forward<Args>(args1)...) {}

C ++ не выведет Args... для вас здесь. Он выведет пакет аргументов только в том случае, если это последние аргументы в вызове функции, и здесь Args... является как последним, так и не последним, поэтому он не будет выведен.

Теперь вы можете использовать make из кортежа до некоторой степени:

template<class...Args0, class...Args1>
screen( std::tuple<Args0...> args0, std::tuple<Args1...> args1 ):
  m_f0(std::make_from_tuple<frame>(std::move(args0))),
  m_f1(std::make_from_tuple<frame>(std::move(args1)))
{}

, который приближает вас (но недостаточно близко). На сайте звонков вы должны сделать:

screen s = {std::forward_as_tuple(f), std::forward_as_tuple(16, 16)};

и теперь оно должно работать.

Используется , но make_from_tuple может быть реализовано еще до или в C ++ 14 .

...