参数包扣减有哪些规则
What are the rules for parameter pack deduction
谁能告诉我为什么这不起作用?
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");
为什么尾巴被推断为空?
来自 cpprefrence - 参数包
解释
...
在主类模板中,模板参数包必须是模板参数列表中的最后一个参数。
在函数模板中,模板参数包可能出现在列表的较早位置,前提是可以从函数参数推导出以下所有参数,或者具有默认参数
和 cpp首选项 - 模板参数推导
从类型中扣除
...
如果P具有包含模板参数列表<T>
或<I>
的形式之一,则该模板参数列表的每个元素Pi都与其A的相应模板参数Ai匹配。如果最后一个Pi是包扩展,则将其模式与A的模板参数列表中的每个剩余参数进行比较。未以其他方式推导的尾随参数包被推导为空参数包。
要完成这项工作,编译器必须能够推断参数。这可以通过重载具有不同模板参数的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:错误:静态断言失败:ab 不以 ac
开头 static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'a', 'c'>()), "ab 不以 ac 开头" ^
a.cpp:24:1: 错误: 静态断言失败: ab 不以 xa 开头 static_assert(startsWith(StaticString<'a', 'b'>(), StaticString<'x', 'a'>()), "ab 不以 xa
开头">
^
演绎也发生在这里StaticString<prefix..., tail...>
,因为它是贪婪的,prefix
拿走一切,tail
是空的。
然后,第二个参数的推论相互冲突。
- 如何反转整数参数包
- cmake如何在fedora工作站中找到boost静态库包
- 此代码是否违反一个定义规则
- 如何将enable-if与模板参数和参数包一起使用
- 生成文件不对文件使用隐式规则
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- 变量可能尚未初始化[MIRA 2012规则9.1,强制性]
- 静态结构和一个定义规则
- 为什么这个音频包络不能通过开关的情况?
- OpenMP:并行更新数组总是需要减少数组吗
- 模板元编程:如何将参数包组合成新的参数包
- 如何将C++闭包与变量参数同时重用——类似于JavaScript
- 尽管遵循了规则,内存泄漏在哪里
- AcquireCredentialsHandleA() 返回 PFX 文件的0x8009030e(安全包中没有可用的凭据
- C ++:在构造函数中使用参数包?
- 参数包扣减有哪些规则
- 具有多个包的参数包匹配规则
- 为什么它是一个使用GCC的令人震惊的函数调用?模板扣减失败
- 模板,良好形成性和零包长度规则
- 给定一个lambda捕获,哪些规则决定结果闭包成员的类型