我编写了一些代码,在给定通用 lambda 函数时检索非自动参数的类型。正如您在下面的代码中看到的那样,想法是使用通用 lambda 调用 connect 函数并为自动参数提供参数(在我的用例中始终位于前面)。所以在下面的代码中,我的目标是检测第二个参数的类型是浮点数。
该代码适用于 clang 3.8,但它不能使用 gcc 6.1.1 编译,所以我想知道这是否是 gcc 中的一个错误,或者这是否只是无效的 c++ 代码?我可以假设通用 lambda 是使用模板化的 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);
}
gcc 给出的错误是这样的:
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
in findArgTypes 会得到相同的结果。
使用以下代码适用于两种编译器:
struct Foo
{
template <typename T>
void operator()(T, float) const {}
};
int main()
{
Foo f;
connect(f, 0);
}