【问题标题】:Howto use a fold expression with a specific type?如何使用具有特定类型的折叠表达式?
【发布时间】:2018-03-19 13:05:40
【问题描述】:

我有一个函数来检查 std::string 是否包含子字符串。我将字符串传递为std::string_view,这样就不会发生复制。

bool containsSubstr(std::string_view str, std::string_view substr)
{
    return str.find(substr) != std::string::npos;
}

我现在想创建一个函数,使用新的 C++17 折叠表达式来检查字符串是否包含多个子字符串。同样,我想通过std::string_views 传递它们。

我该怎么做?

template<typename... Substrs>
bool containsAllSubstr(std::string_view str, Substrs... substrs)
{
    return  (containsSubstr(str, substrs) && ...);
}

据我所知,上面的版本会将子字符串作为它们进来的类型。所以std::string 将被复制。如何将类型修复为std::string_view?比如:

template<> // does not compile
bool containsAllSubstr(std::string_view str, std::string_view... substrs)
{
    return  (containsSubstr(str, substrs) && ...);
}

【问题讨论】:

    标签: c++ c++17 fold-expression


    【解决方案1】:

    您不能拥有特定类型的函数参数包。但这很好(一旦添加const&amp;):

    template <typename... Substrs>
    bool containsAllSubstr(std::string_view str, Substrs const&... substrs)
    {
        return  (containsSubstr(str, substrs) && ...);
    }
    

    这不会产生任何副本,并且如果您传入不可转换为string_view 的内容,则不会编译。如果你想让它对 SFINAE 友好,可以添加一个条件:

    template <typename... Substrs,
        std::enable_if_t<(std::is_convertible_v<Substrs const&, std::string_view> && ...), int> = 0>
    bool containsAllSubstr(std::string_view str, Substrs const&... substrs)
    {
        return  (containsSubstr(str, substrs) && ...);
    }
    

    或者,如果您愿意对语法稍作改动,您可以采用一个数组:

    template <size_t N>
    bool containsAllSubstr(std::string_view str, std::string_view (&substrs)[N]);
    

    但是你实际上并没有立即拥有一个包。但是,你可以只写一个循环。或者,如果您根本不需要编译时大小:

    bool containsAllSubstr(std::string_view str, std::initializer_list<std::string_view> substrs);
    

    【讨论】:

    • std::initializer_list&lt; std::string_view &gt;?
    • @Yakk 或者,如果您实际上不需要编译时大小(这...您可能不需要?)
    • 在我的代码库中,我实际上会使用my_ns::span&lt; std::string_view &gt;,而我的span 有一个std::initializer_list&lt; remove_const&lt;T&gt; &gt; ctor。它运行良好,这意味着我可以传入数组、{} 封闭列表(包括空)、向量或其他任何东西。
    • @Yakk 这……有用吗? initializer_list 不会被销毁并留下悬空指针吗?
    • 它一直持续到创建初始化列表的完整表达式的末尾。这比函数调用要长。可能需要一个const&amp; 以确保其正常工作。
    猜你喜欢
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-08
    • 2023-03-31
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多