Немного предыстории: компоновщики не понимают перегрузку функций - они понимают только имена функций, как в языке Си. Вот почему компиляторы C ++ манипулируют именами ваших функций. void foo(int)
становится _Z3fooi
. Искаженное имя кодирует типы всех аргументов. Если ваша функция возникла в результате создания шаблона, все аргументы шаблона также будут закодированы. Если они сами являются шаблонными классами, их аргументы шаблона кодируются и т. Д. Рекурсивно, пока не будут достигнуты примитивные типы, такие как int или указатели на функции.
Лямбда усложняет задачу, потому что каждая лямбда должна иметь отдельный тип Это не так уж плохо для лямбд, определенных в функциях:
auto foo() { return [](){}; }
auto bar() { return [](){}; }
foo
и bar
возвращают различные типы. Если вы затем передадите их в другой шаблон функции, имя этого шаблона будет искажено, как если бы оно было foo::__lambda1
или что-то в этом роде.
Если лямбды появятся в decltype
, это нарушит этот механизм.
void bar(decltype([](){}));
void bar(decltype([](){})) {}
Это прототип и определение? Или это две разные перегрузки bar
? Как идентифицировать их по единицам перевода (как искажать названия)?
До сих пор C ++ запрещал даже задавать этот вопрос. Документ, на который вы ссылаетесь, дает ответ: такие вещи не могут иметь связи. Даже не пытайтесь их калечить.