c++ - 如何为通用 lambda 参数定义模板参数?

标签 c++ templates lambda c++17 template-argument-deduction

<分区>

解释:

CLion 及其标准编译器给我一个错误,即“候选模板 [被] 忽略”,当我将 lambda 编写为以 lambda 作为参数的通用函数的参数时。 此 lambda 采用通用类型 T 并返回另一个未知类型 A

我正在编写的容器类应该支持像 Scala 中的这些功能操作或来自 Java Stream API 的功能操作。

准确地说: map 功能会带来很大的问题。它作为一个名为 Sequence 的类中的成员函数实现,该类采用通用参数 T。 它应该采用已知类型 T 的元素(实际上它遍历整个序列)并将其转换为未知类型 A。 实现本身不是问题,但我无法使用我知道的 lambda 语法调用该函数。

代码:

Sequence.h

template< typename T >
class Sequence {
public:
    template< typename A >
    auto map( std::function< A( const T ) > function ) const {
        auto sequence = new Sequence< A >;
        for ( const T& element : *this ) {
            sequence->push( function( element ) );
        }
        return *sequence;
    }
}

main.cpp

int main() {
    Sequence< uint32_t > a;
    a.push( 20 );
    a.push( 30 );
    a.push( 40 );

    a.map( []( uint32_t c ) -> uint32_t {
        return c * c;
    } );
    return 0;
}

据我所知,lambda 被初始化,这 采用 std::uint32_t 类型的参数并返回 std::uint32_t 类型的值。 此时似乎无法推断通用参数 A

错误堆栈:

main.cpp:21:7: error: no matching function for call to 'Sequence<unsigned int>::map(main()::<lambda(uint32_t)>)'
     } );

Sequence.h:143:10: note: candidate: template<class A> auto Sequence<T>::map(std::function<A(T)>) const [with A = A; T = unsigned int]
     auto map( std::function< A( const T ) > function ) const {

note:   template argument deduction/substitution failed:
main.cpp:21:7: note:   'main()::<lambda(uint32_t)>' is not derived from 'std::function<A(unsigned int)>'
     } );

提前致谢!

最佳答案

忽略 const问题,你有一种先有鸡还是先有蛋的问题。

的确,您的 lambda 可以转换为 std::function<std::uint32_t(std::unit32_t)> .

但 lambda 不是 std::function<std::uint32_t(std::unit32_t)> 也是事实所以编译器无法推断出 A .

如果编译器不能推导出A , 无法将 lambda 转换为 std::function<A(T)> .

您显然可以显式显示正确的 std::function键入调用 map()

a.map(std::function<std::uint32_t(std::uint32_t)>{[]( uint32_t c ) -> uint32_t {
    return c * c;
}});

并且,考虑到您使用的是 C++17(因此您可以使用 std::function 的推导指南),同时推导 std::function 的模板参数

a.map(std::function{[]( uint32_t c ) -> uint32_t {
    return c * c;
}});

但是,再次使用 std::function 的模板推导指南,写的怎么样mat()接受一个简单的可调用和推导 A从中?

我的意思是...下面的内容怎么样?

template <typename F>
auto map( F && func ) const {
    using A = typename decltype(std::function{std::forward<F>(func)})::result_type;

    auto sequence = new Sequence< A >;
    for ( const T& element : *this ) {
        sequence->push( std::forward<F>(func)( element ) );
    }
    return *sequence;
}

(注意:代码未经测试)。

你也可以推导出A , 没有 std::function演绎指南(在 C++17 之前),正如 Michael Kenzel 所建议的那样。

关于c++ - 如何为通用 lambda 参数定义模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55784120/

相关文章:

c# - 存储对实例方法的静态引用?

c# - new Action() 和 lambda 有什么区别?

c++ - Lambda 捕获和内存管理

c++ - 在 Android NDK 中用 C++ 调用 Java 对象 - 使用什么 IDE?

c++ - C++调试器

c++ - 我可以根据模板参数将某个值传递给成员构造函数吗?

c++ - 从模板抽象类继承

c++: what(): std::bad_alloc 错误

c++ - Qt 5- QTextEdit 恢复为默认字体

mongodb - AWS Mongo QuickStart 从未完成