Здравствуйте, koenjihyakkei, Вы писали:
K>Ну да, там пишется, что это не работает, но это я и так уже понял. А вот почему и как это обойти, вот вопрос.
Вы уверены что все компилируется? У вас B параметризуется классом A, который в конструкторе принимает единственный аргумент, а вы туда передаете параметр-пак.
Здравствуйте, Videoman, Вы писали:
V>В любом случае, по ходу здесь typename... Args жадничает и раскрывается в <int, int> , а для v ничего не остается. :xz:
Определённо стоит прочитать ссылку, которую сами и дали :)
По правилам языка parameter pack в приведённом примере всегда раскрывается в пустой <>. О том, что он раскрывается в пустой к тому же можно догадаться ещё и прочтя сообщение компилятора: ведь он сообщает, что фактических параметров слишком много, а не слишком мало.
Здравствуйте, Videoman, Вы писали:
V>В любом случае, по ходу здесь typename... Args жадничает и раскрывается в <int, int> , а для v ничего не остается.
Как раз наоборот — Args раскрывается в пустой пак:
candidate constructor [with Args = <>] not viable: requires single argument 'v', but 2 arguments were provided
Здравствуйте, Videoman, Вы писали:
V>Вы уверены что все компилируется? У вас B параметризуется классом A, который в конструкторе принимает единственный аргумент, а вы туда передаете параметр-пак.
Здравствуйте, watchmaker, Вы писали:
W>По правилам языка parameter pack в приведённом примере всегда раскрывается в пустой <>. О том, что он раскрывается в пустой к тому же можно догадаться ещё и прочтя сообщение компилятора: ведь он сообщает, что фактических параметров слишком много, а не слишком мало.
То что parameter pack жадный предположил читая вот тут. То что по стандарту параметр-пак тут раскрывется в <> я впервые от вас слышу. А можно ссылку где это описано?
Здравствуйте, Videoman, Вы писали:
V>Не понял, зачем вы используется параметр-пак если у вас всегда только два аргумента?
Это просто пример, в рельности должно было бы быть множество классов с разным количеством аргументов. И мысль такая, что мы инициализируем самый верхний класс в цепочке наследования, он откусывает от параметр пака нужные себе аргументы, а оставшийся пак спускает дальше родителю, и так далее.
Здравствуйте, koenjihyakkei, Вы писали:
K>Это просто пример, в рельности должно было бы быть множество классов с разным количеством аргументов. И мысль такая, что мы инициализируем самый верхний класс в цепочке наследования, он откусывает от параметр пака нужные себе аргументы, а оставшийся пак спускает дальше родителю, и так далее.
Идею понял. Тогда, если watchmaker прав и parameter pack по стандарту настолько щедр, что ничего себе не берет, то вариант у вас только поменять аргументы местами, что бы parameter pack всегда был в конце. Но конечно было бы интересно если бы кто-нибудь разъяснил такое поведение.
Здравствуйте, koenjihyakkei, Вы писали:
K>Можно ли как то такое починить или это в принципе не должно работать?
Можно вытащить последний аргумент например так:
template<typename T>
struct identity
{
using type = T;
};
template<typename... Ts>
struct select_last
{
using type = typename decltype((identity<Ts>{}, ...))::type;
};
template<typename ...Args>
decltype(auto) get_last(Args&&... args)
{
return (std::get< sizeof...(Args) - 1 >(std::tie(std::forward<Args>(args)...)));
}
template<typename T>
struct B : public T
{
template<typename... Args>
B(Args&&... args, int i) : T(std::forward<Args>(args)...), _v(get_last(std::forward(args))) {}
}
А вот как взять из args все кроме последнего не уверен, что возможно.
Обновление: Хотя наверное и возможно. Упаковать args в std::tuple, убрать последний элемент и распаковать обратно.
Если 'A' принимал бы в конструкторе tuple тогда можно было бы создать кортеж и убрать последний элемент.
Супер, спасибо! Но к сожалению не подойдет, проблема в том, что и копи, и мув конструкторы запрещены.
Схема такая, что есть один базовый тяжелый класс и над ним надстраиваются классы миксины, у которых может быть произвольное количество аргументов в конструкторе.
Здравствуйте, koenjihyakkei, Вы писали:
K>Здравствуйте, _NN_, Вы писали:
K>Супер, спасибо! Но к сожалению не подойдет, проблема в том, что и копи, и мув конструкторы запрещены.
K>Схема такая, что есть один базовый тяжелый класс и над ним надстраиваются классы миксины, у которых может быть произвольное количество аргументов в конструкторе.
В C++17 не будет ни копирования не перемещения, а будет отложенная материализация:
Здравствуйте, koenjihyakkei, Вы писали:
K>Здравствуйте, _NN_, Вы писали:
_NN>>В C++17 не будет ни копирования не перемещения, а будет отложенная материализация:
K>Ну вроде и так С++17, а ваш код с запрещенным копи конструктором не компилируется: https://gcc.godbolt.org/z/owCH7y
Ну да, там требуется либо копия либо перемещение.
Надо подумать как передать набор аргументов без вспомогательной функции.
Здравствуйте, koenjihyakkei, Вы писали:
K>Здравствуйте, _NN_, Вы писали:
_NN>>В C++17 не будет ни копирования не перемещения, а будет отложенная материализация:
K>Ну вроде и так С++17, а ваш код с запрещенным копи конструктором не компилируется: https://gcc.godbolt.org/z/owCH7y
Кстати компилятор MSVC 16.5 код собирает и похоже как не должен .