【问题标题】:Use std::array in function using 'overloaded' lambdas在使用“重载”lambda 的函数中使用 std::array
【发布时间】:2021-10-07 08:03:13
【问题描述】:

我希望在 C++20 中执行以下操作:

template <class... Ts>
struct overloaded : Ts... {
    using Ts::operator( )...;
};

// Updated to work with C++17
#if (_cplusplus != 202002L)    // check for C++17 or C++20
// Deduction guide, google `CTAD for aggregates` for more info
template <typename... Ts>
overloaded(Ts...) -> overloaded<Ts...>;    // not needed before C++20
#endif

template <typename T, long int C = 0>
void emit(T const& data) {

    auto emit = overloaded {

        [&](const auto& value) {
            mOs << value;
        },
        [&](const uint8_t& value) {
            mOs << std::showbase << (uint16_t)value;
        },
        [&](const std::array<T, C>& value) {
           for (auto& v : value) { // error: can't increment 0 size std::array
               mOs << v;
           }
        },
        // bunch more lambdas
    };
    emit(data);
}

// invoked by
emit(1);

既然需要计数,如何捕获 std::array?

如果不将 C 设置为零,所有其他 lambdas 都会失败。

可能不可能,但我想我会问的。

【问题讨论】:

    标签: c++ lambda c++20 stdarray


    【解决方案1】:

    您可以使用 C++20 中引入的 lambdas 模板参数列表。 lambdas 参数不是std::array&lt;T,C&gt;,而是T,而T 是一些std::array&lt;S,C&gt;

    #include <iostream>
    #include <array>
    
    template <class... Ts>
    struct overloaded : Ts... {
        using Ts::operator( )...;
    };
    
    template <typename T>
    void emit(T const& data) {
        std::ostream& mOs = std::cout;
    
        auto emit = overloaded {
            [&](const auto& value) {
                mOs << value;
            },
            [&](const uint8_t& value) {
                mOs << std::showbase << (uint16_t)value;
            },
            [&]<typename S,size_t C>(const std::array<S, C>& value) {
               for (auto& v : value) { 
                   mOs << v;
               }
            },
            // bunch more lambdas
        };
        emit(data);
    }
    int main(){
        // invoked by
        std::array<int,42> x;
        emit(x);
    }
    

    Live Demo

    【讨论】:

    • 感谢您的快速回复。效果很好。还解决了如何处理向量,这是我的下一个任务。这也适用于 GCC 11 中的 C++17。
    • @rm1948 Lambda 模板参数是在 C++20 中引入的。如果它在 C++17 模式下与 GCC 11 一起使用,那么这就是 GCC 扩展。您应该考虑启用-pedantic,以便编译器can warn you of such cases
    • @Human-Compiler - 你是对的。它是 GCC 的扩展。它适用于 GCC 7.1 和 Clang 9.0,只是信息......
    猜你喜欢
    • 2019-05-04
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多