Следующий фрагмент компилирует без ошибок с Clang 4.0, но GCC 7.0 производит (обратите внимание на использование -std = С++ 1z flag).
using FuncT = int (*)(double);
template <FuncT FUNC>
int temp_foo(double a)
{
return FUNC(a);
}
int foo(double a)
{
return 42;
}
void func()
{
auto lambda = [](double a) { return 5; };
struct MyStruct
{
static int foo(double a) { return 42; }
};
temp_foo<foo>(3);
temp_foo<static_cast<FuncT>(lambda)>(3);
temp_foo<MyStruct::foo>(3);
}
В частности, GCC жалуется, что как лямбда, так и метод вложенного класса не имеют привязки, поэтому они не могут использоваться как аргумент шаблона непигового типа.
По крайней мере, для лямбда-случая я считаю, что Clang правильный (и GCC ошибочен), поскольку (цитируя cppreference, оператора преобразования):
Значение, возвращаемое этой функцией преобразования, является указателем на функция с связью языка С++, которая при вызове имеет тот же эффект как вызов оператора вызова функции закрытия объекта непосредственно.
Неправильное поведение GCC?