用于连接 string_views 的折叠表达式

问题描述 投票:0回答:1

我想要一个折叠表达式函数来连接 string_views。但我尝试过的代码不起作用。我做错了什么?

template<typename Allocator, typename Char, typename Traits>
auto sv_concat( std::basic_string_view<Char, Traits> svs ... )
{
    basic_string<Char, Traits, Allocator> str;
    str.reserve( (svs.length() + ...) );
    ((str += svs), ...);
    return str;
}

这是 clang++ 18 个错误:

test.cpp:14:31: error: pack expansion does not contain any unexpanded parameter packs
   14 |         str.reserve( (svs.length() + ...) );
      |                       ~~~~~~~~~~~~   ^
test.cpp:15:17: error: pack expansion does not contain any unexpanded parameter packs
   15 |         ((str += svs), ...);
      |          ~~~~~~~~~~~~  ^
c++ c++17
1个回答
0
投票

您的代码中没有参数包。我将只讨论这个问题。可变参数模板可用于实现可变参数函数,非可变参数模板则不能(除了 c 省略号)。

在可变参数模板中,您可以限制模板的多种类型全部相同,或者是同一模板的所有实例。然而,让我们从更简单的开始......

而不是

std::string
,我在示例中使用了一些带有单个模板参数的
Foo
。因为我知道我需要使用部分专业化,所以我使用类模板
bar
代替函数模板。

template <typename T>
struct foo {};

template <typename ... T>
struct bar;

template <typename ...U>
struct bar<foo<U>...>
 {
    void operator()() {
        std::cout << sizeof...(U);
    }
};

可以添加的其他专业化,

bar
只能使用作为
foo
实例化的类型进行实例化。

另一种途径是对特征进行部分特化:

 template <typename T> struct is_foo : std::false_type {};
 template <typename U> struct is_foo<foo<U>> : std::true_type {};
 template <typename T> constexpr bool is_foo_v = is_foo<T>::value;

并用它来限制

bar
。 SFINAE 因为我是老派:

template <typename ... T>
auto bar() -> std::enable_if_t< std::conjunction_v<is_foo<T>...> > 
{ std::cout << sizeof...(T);}

现场演示

有了概念,你就有了更好的方法来做同样的事情,但原则上它会做同样的事情。

© www.soinside.com 2019 - 2024. All rights reserved.