Как написать общую переменную лямбду, которая отбрасывает свои параметры?

Я хочу написать лямбду, которая принимает произвольное количество аргументов по универсальной ссылке и полностью их игнорирует. Очевидным методом будет использование синтаксиса для универсального пакета параметров с переменными параметрами и опускание имени параметра:

auto my_lambda = [](auto&&...) { return 42; };

Это прекрасно работает (с GCC 4.9.2), пока я попробуйте передать нетривиально копируемый объект:

struct S { S() {} S(S const&) {} };
my_lambda("meow", 42, S{});
^ error: cannot pass objects of non-trivially-copyable type 'struct S' through '...'

В чем дело? Неправильный ли мой код или это ошибка в gcc?

В любом случае, какой лучший обходной путь? Я обнаружил, что присвоение имени параметру работает, но затем натолкнулся на предупреждение о неиспользованном параметре:

auto my_lambda = [](auto&&... unused) { return 42; };
^ error: unused parameter 'unused#0' [-Werror=unused-parameter]
^ error: unused parameter 'unused#1' [-Werror=unused-parameter]
^ error: unused parameter 'unused#2' [-Werror=unused-parameter]

Как вы подавляете предупреждение о неиспользованном параметре в пакете параметров шаблона?

7

Решение

Это ошибка разбора в GCC (о котором вы сами сообщили!). auto&&... является грамматически неоднозначным и может быть проанализирован как эквивалент auto&&, ... или объявление пакета параметров (технически, вопрос заключается в том, ... является частью Параметр декларирование придаточного или абстрактно-описатель); стандарт говорит, что он должен быть проанализирован как последний; GCC разбирает это как первое.

Именование пакета разрешает неоднозначность анализа:

auto my_lambda = [](auto&&... unused) { return 42; };

Чтобы подавить предупреждение, можно применить __attribute__((__unused__)) (или, как предложил @Luc Danton, [[gnu::unused]]):

auto my_lambda = [](auto&&... unused __attribute__((__unused__))) { return 42; };

или использовать sizeof...

auto my_lambda = [](auto&&... unused) { (void) sizeof...(unused); return 42; };
10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]