# 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 предоставляет следующие три макроса:

- '__FUNCTION__' – выводит имя функции, не опуская при этом его область объявления. Например, для лямбды внутри функции main мы получим такой вывод: 'main::<lambda_....>::operator ()';
- '__FUNCSIG__' – выводит полную сигнатуру функции. Так же может быть полезным в связке с лямбдой: 'auto __cdecl main::<lambda_....>::operator ()(void) const';
- '__FUNCDNAME__' – выводит декорированное имя функции. Это достаточно специфичная информация, поэтому она не подходит для полноценной замены '__func__'.

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

- '__FUNCTION__' – выводит то же имя, что и стандартный '__func__';
- '__PRETTY_FUNCTION__' – выводит полную сигнатуру функции, например для лямбды может быть следующий вывод: 'auto main()::(anonymous class)::operator()() const'.