V1056. The predefined identifier '__func__' always contains the string 'operator()' inside function body of the overloaded 'operator()'.

Анализатор обнаружил использование идентификатора '__func__' в теле перегруженного оператора '()'.

Рассмотрим пример:

class C
{
  void operator()(void)
  {
    std::cout << __func__ << std::endl;
  }
};

void foo()
{
  C c;
  c();
}

При запуске будет выведено 'operator()'. На первый взгляд, это вполне ожидаемое поведение для подобного кода, поэтому перейдем к более неочевидному примеру:

void foo()
{
  auto lambda = [] () { return __func__; };
  std::cout << lambda() << std::endl;
}

Важно учитывать тот факт, что '__func__' не является переменной в привычном смысле этого слова, поэтому следующие варианты не сработают, и по-прежнему будет выведено 'operator()':

void fooRef()
{
  auto lambda = [&] () { return __func__; };
  std::cout << lambda() << std::endl;
}
void fooCopy()
{
  auto lambda = [=] () { return __func__; };
  std::cout << lambda() << std::endl;
}

Чтобы исправить это в случае с лямбдой, необходимо передать '__func__' явно через список захвата:

void foo()
{
  auto lambda = [func = __func__] () { return func; };
  std::cout << lambda() << std::endl;
}

Для более полноценного вывода имени функции даже внутри перегруженного 'operator()' или тела лямбды можно воспользоваться специфичными для платформы/компилятора макросами. Так, компилятор MSVC предоставляет следующие три макроса:

Для компиляторов Clang и GCC доступны следующие макросы: