gpt4 book ai didi

c++ - 参数包扣减规则是什么

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:26:38 24 4
gpt4 key购买 nike

谁能告诉我为什么这不起作用?

template<char... cs> struct StaticString {};

template<char... tail, char... prefix>
constexpr bool startsWith(StaticString<prefix..., tail...>, StaticString<prefix...>)
{
return true;
}

static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'a'>()),
"ab starts with a");

为什么tail被推导为空?

最佳答案

来自 cpprefrence - Parameter pack

Explanation
...
In a primary class template, the template parameter pack must be the final parameter in the template parameter list.
In a function template, the template parameter pack may appear earlier in the list provided that all following parameters can be deduced from the function arguments, or have default arguments

cppreference - Template argument deduction

Deduction from a type
...
If P has one of the forms that include a template parameter list <T> or <I>, then each element Pi of that template argument list is matched against the corresponding template argument Ai of its A. If the last Pi is a pack expansion, then its pattern is compared against each remaining argument in the template argument list of A.

A trailing parameter pack that is not otherwise deduced, is deduced to an empty parameter pack.


要使其工作,编译器必须能够推导出参数。这可以通过重载 startsWith 来完成。具有不同的模板参数。您可以从最后一部分开始,其中只有第一个 StaticString是否还有剩余参数

template<char... tail>
constexpr bool startsWith(StaticString<tail...>, StaticString<>)
{
return true;
}

然后你有一个失败的startsWith ,其中两个StaticString不同

template<char... tail1, char... tail2>
constexpr bool startsWith(StaticString<tail1...>, StaticString<tail2...>)
{
return false;
}

最后是一个重载,其中前缀被剥离并比较剩余部分

template<char prefix, char... tail1, char... tail2>
constexpr bool startsWith(StaticString<prefix, tail1...>, StaticString<prefix, tail2...>)
{
return startsWith(StaticString<tail1...>(), StaticString<tail2...>());
}

现在您可以 static_assert有各种论点,例如

static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'a'>()),
"ab starts with a");
static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'a', 'b'>()),
"ab starts with ab");
static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'a', 'c'>()),
"ab does not start with ac");
static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'x', 'a'>()),
"ab does not start with xa");

将导致(Ubuntu 16.04,g++ 5.4)

a.cpp:23:1: error: static assertion failed: ab does not start with ac
static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'a', 'c'>()), "ab does not start with ac"
^
a.cpp:24:1: error: static assertion failed: ab does not start with xa
static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'x', 'a'>()), "ab does not start with xa"
^

关于c++ - 参数包扣减规则是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48641936/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com