Я написал код, который извлекает типы неавтоматических параметров при предоставлении общей лямбда-функции. Как вы можете видеть в приведенном ниже коде, идея состоит в вызове функции connect с общей лямбдой и предоставлении аргументов для автоматических параметров (которые всегда будут в начале в моем случае использования). Поэтому в приведенном ниже коде моя цель состояла в том, чтобы обнаружить, что второй параметр имеет тип float.Обнаружение типов параметров из общей ошибки лямбда-компиляции с помощью GCC
Код работает нормально с clang 3.8, но он не компилируется с gcc 6.1.1, поэтому мне было интересно, было ли это ошибкой в gcc или это просто недопустимый код C++? Могу ли я предположить, что общая лямбда реализована с помощью функции templated operator() или это специфичная для компилятора?
template <typename Functor, typename... AllArgs, typename... ProvidedArgs>
void findArgTypes(void(Functor::*)(AllArgs...) const, Functor, ProvidedArgs...)
{
// AllArgs == int, float
// ProvidedArgs == int
}
template <typename Func, typename... ProvidedArgs>
void connect(Func func, ProvidedArgs... providedArgs)
{
findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...);
}
int main()
{
int tmp = 0;
connect([&](auto, float){ ++tmp; }, 0);
}
Ошибка, НКУ дает это:
main.cpp: In instantiation of ‘void connect(Func, ProvidedArgs ...) [with Func = main()::<lambda(auto:1, float)>; ProvidedArgs = {int}]’:
main.cpp:16:33: required from here
main.cpp:11:17: error: no matches converting function ‘operator()’ to type ‘void (struct main()::<lambda(auto:1, float)>::*)() const’
findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...);
~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:16:27: note: candidate is: template<class auto:1> main()::<lambda(auto:1, float)>
connect([](auto, float){}, 0);
^
Удаление const
в findArgTypes дает тот же результат.
Используя следующий код работает с обоими составителями:
struct Foo
{
template <typename T>
void operator()(T, float) const {}
};
int main()
{
Foo f;
connect(f, 0);
}
Этот код, похоже, компилируется с gcc, но не с clang. Но изменение моего кода для принятия 'void (*) (AllArgs ...)' как первого параметра findArgTypes по-прежнему дает ту же ошибку с gcc (и больше не работает с clang). Захват локальной переменной также, похоже, не имеет значения. – texus
Вам нужны две перегруженные функции - одна для бесплатных функций, одна для функций объекта - или просто немного измените ваш дизайн ... – PiotrNycz
clang может быть неправильным - см. Пример со связанной страницы: 'int & (* fpi) (int *) = [] (авто * a) -> auto & {return * a; }; // ok' – PiotrNycz