c++ - 从通用 lambda 检测参数类型 - GCC 编译错误

标签 c++ gcc lambda c++14 generic-lambda

我编写了一些代码,在给定通用 lambda 函数时检索非自动参数的类型。正如您在下面的代码中看到的,这个想法是使用通用 lambda 调用 connect 函数,并为自动参数提供参数(在我的用例中,它始终位于最前面)。所以在下面的代码中,我的目标是检测第二个参数是 float 类型。

代码在 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);
                           ^

删除 findArgTypes 中的 const 会得到相同的结果。

使用以下代码适用于两种编译器:

struct Foo
{
    template <typename T>
    void operator()(T, float) const {}
};

int main()
{
    Foo f;
    connect(f, 0);
}

最佳答案

你有错误是因为你期望仿函数(对象)但是带有空捕获的 lambda 可以转换为自由函数:

int main() {
    using function = void (*)(int, float);
    function a = [](auto, float){};
}

参见 lambda from cppreference :


对于你的问题的最新版本,实现满足两个编译器:

template <typename Func, typename... ProvidedArgs>
void connect(Func func, ProvidedArgs... providedArgs)
{
    auto mf = &Func::template operator()<ProvidedArgs...>;
    findArgTypes(mf, func, providedArgs...);
}

我认为这是 gcc 编译器错误,gcc 需要这个 auto 局部变量才能正常工作...

顺便说一句,一个问题 - clang 中的一个错误,gcc 中的一个错误 - 我真的建议你找到更简单的方法来实现你的目标 - 也许考虑只使用 std::function 而不是很新鲜通用 lambda?

关于c++ - 从通用 lambda 检测参数类型 - GCC 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37971428/

相关文章:

haskell - 基于 lambda/church bool 值的类型同义词

c++ - 关于使迭代器失效

c++ - 如何在关联指针时编写无错误代码?

c - 如何在现代系统上测试缓冲区溢出?

c++ - 将带有 capture 的 lambda 传递给模板化函数

java - Lambda 表达式不工作,被终止

c++ - 将 4 个套接字字节转换为一个 int

c++ - 无法使用 #pragma omp parallel for 创建多个线程

c++ - gcc (mac/linux) 错误没有匹配的调用函数,而 VisualStudio 编译正常

qt - 如何抑制标题中包含的文件的警告