В следующем определении функции шаблона я дважды напишу относительно длинное выражение details::transform(std::forward<T>(t))
, где t
- пакет параметров.
Как я могу это учитывать?
auto pack = details::transform(std::forward<T>(t))
конечно не работает.
template<class ...T>
void f(T&&... t)
{
auto check = (details::transform(std::forward<T>(t)) && ...);
if (check == false) {
return;
}
details::act(details::transform(std::forward<T>(t))...);
}
Для целей тестирования здесь представлена полная программа для coliru.
3 ответа
В C ++ есть печальная правда. Пересылка может стать кластером токенов. И чем сложнее выражение, которому нужно что-то передать, тем более болезненным оно может стать.
К сожалению, единственный способ, которым я знаю, чтобы смягчить это, это с препроцессором ...
#define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
Имея это в виду, мы можем реорганизовать вашу функцию, чтобы использовать IILE для генерации этого пакета только один раз:
template<class ...T>
void f(T&&... t)
{
[](auto&&... pack) {
auto check = (FWD(pack) && ...);
if (check == false) {
return;
}
details::act(FWD(pack)...);
}(details::transform(FWD(t))...);
}
Таким образом, вы вызываете transform
только один раз для аргумента. Я предполагаю, что это чистая цель. В противном случае вы можете использовать препроцессор для генерации чего-то более простого без лямбды.
Вы не можете сделать это. Ваши два вариационных выражения расширяются до разных шаблонов. Лучшее, что вы можете сделать, это что-то вроде этого (без макросов):
template<class ...T>
void f(T&&... t)
{
using details::transform;
// (T&&)t == std::forward<T>(t);
auto check = (transform((T&&)t) && ...);
if (check == false) {
return;
}
details::act(transform((T&&)t)...);
}
Вы могли бы использовать макрос.
#define FORWARD_TRANSFORM(type, var) details::transform(std::forward<type>(var))
Тогда ваша функция становится
template<class ...T>
void f(T&&... t)
{
auto check = (FORWARD_TRANSFORM(T, t) && ...);
if (check == false) {
return;
}
details::act(FORWARD_TRANSFORM(T, t)...);
}
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который будет скомпилирован с помощью компилятора C ++). Используйте тег, зависящий от версии, для вопросов, связанных с конкретной редакцией стандарта [C ++ 11], [C ++ 14], [C ++ 17] или [C ++ 20] и т. Д.