- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
谁能告诉我为什么这不起作用?
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/
我是一名优秀的程序员,十分优秀!