Здравствуйте, koenjihyakkei, Вы писали:
K>Здравствуйте, _NN_, Вы писали:
_NN>>В C++17 не будет ни копирования не перемещения, а будет отложенная материализация:
K>Ну вроде и так С++17, а ваш код с запрещенным копи конструктором не компилируется: https://gcc.godbolt.org/z/owCH7y
Можно перенести тело вспомогательных функций в сам класс и тогда всё собирается:
Здравствуйте, 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 код собирает и похоже как не должен .
Это уже интереснее, мысль понятна, спасибо. Если обернуть еще макросами, то можно сократить количество вспомагательного кода, тогда менее верятно, что меня с этим пошлют А то эти struct B не только я буду писать.
Здравствуйте, koenjihyakkei, Вы писали:
K>Здравствуйте, _NN_, Вы писали:
K>Это уже интереснее, мысль понятна, спасибо. Если обернуть еще макросами, то можно сократить количество вспомагательного кода, тогда менее верятно, что меня с этим пошлют А то эти struct B не только я буду писать.
Полагаю можно поиграться с кодом и упростить, может с CRTP или другим подходом.
Всё же, если не критично ставить параметры класса вначале, а не в конце, то это будет лучшим решением.
Если кому интересно, поигрался с версией от _NN_ и пришел к следующему варианту. Буду благодарен если кто подскажет, как можно улучшить.
Единственно у него есть один недостаток и возможно достаточно серьезный: не работает implicit conversion — компиляция падает с ошибкой "recursive template instantiation exceeded maximum depth", что в принципе логично.
То есть если конструктор ждет unsigned, а передается 123, а не 123u, то ошибка.
Причем если не менять параметр template-depth (по умолчанию он 1024) то компиляция может занимать приличное время. В общем неприятная ситуация получается.
Здравствуйте, koenjihyakkei, Вы писали:
K>Здравствуйте, koenjihyakkei, Вы писали:
K>Если кому интересно, поигрался с версией от _NN_ и пришел к следующему варианту. Буду благодарен если кто подскажет, как можно улучшить. K>Единственно у него есть один недостаток и возможно достаточно серьезный: не работает implicit conversion — компиляция падает с ошибкой "recursive template instantiation exceeded maximum depth", что в принципе логично. K>То есть если конструктор ждет unsigned, а передается 123, а не 123u, то ошибка. K>Причем если не менять параметр template-depth (по умолчанию он 1024) то компиляция может занимать приличное время. В общем неприятная ситуация получается.
Что-то сложно получилось.
Да ещё и макрос думаю упростить можно.
Кстати, нужно использовать Args&&... , чтобы избежать копирования