#опытным
Используют атрибуты функций не только лишь все, мало кто знает, куда их можно пихать.
Есть на самом деле 3 легальных места для навешивания атрибутов на функцию.
1️⃣ Перед типом возвращаемого значения:
[[deprecated]] int foo() { return 42; }Тогда он работает при непосредственном использовании функции.
foo();
// warning: 'int foo()' is deprecated
2️⃣ После имени функции:
int foo [[deprecated]] () { return 42; }В таком виде атрибут тоже применяется к самой функции.
3️⃣ После параметров:
int foo() [[gnu::deprecated]] { return 42; }Тогда атрибут применяется к типу функции, а не к самой функции. Разница вот в чем:
int foo() [[gnu::deprecated]] { return 42; }
int main() {
foo(); // no warnings
using FuncType = decltype(foo); // use of type is deprecated
}Обычный вызов функции прекрасно компилируется. Но вот использование типа функции через decltype помечается как устаревшее.
Причем gcc и clang по-разному интерпретируют эту ситуацию. Clang говорит, что gnu::deprecated нельзя применять к типам и игнорирует атрибут. Вот ссылка на годболт для интересующихся.
Соответственно, в лямбде в тех же местах можно ставить атрибуты:
auto complicated_compute = [] [[nodiscard]] () [[gnu::deprecated]] {
return 2 * 2;
};Признавайтесь, знали?)
Have your own opinion. Stay cool.
#cppcore