我尝试编写一个函数来检查“http::verb”是否是使用可变参数模板的“允许”。这是我最初使用在线示例编写的代码:
template<typename... Args>
void CheckMethod(const http::verb& received, const Args&... allowed) const {
if((received != allowed) && ...) {
throw ApiError("method is not allowed")
}
}
但是,这不会编译并导致错误:
error: expression contains unexpanded parameter pack 'allowed'
386 | if((received != allowed) && ... ) {
| ^ ~~~~~~~
1 error generated.
解决这个问题的是另一组括号:
if( ((received != allowed) && ...) )
我参考的问题: 用于检查变量是否等于可变参数之一的可变宏
那么,为什么没有额外的括号就不起作用呢?这与表达式的解包方式有关吗?
upd:我发现据说更好的方法是写
if(((received != allowed) && ...) == false) {
有人可以解释一下如何以及为什么这样更好(如果有的话)?
你问:
为什么没有额外的括号就不起作用?
无聊的答案是,这就是 C++ 语法的工作原理。
如果你看这里:https://en.cppreference.com/w/cpp/language/if你会看到一个简单的
if
语句(如果我们删除可选的东西)是:
if ( condition ) statement-true
因此,
if (1==2) doStuff();
有效,但if 1==2 doStuff();
无效; ()
不见了。
然后你可以查看:https://en.cppreference.com/w/cpp/language/fold,看到一个简单的折叠表达式是:
( pack op ... )
这意味着
()
再次成为语法的非可选部分。因此,如果您想将此折叠表达式作为 if
的条件,那么它只需: if (( pack op ...)) statement-true
因为内部 ()
是折叠的非可选部分,而外部是折叠的非可选部分。 if
的非可选部分。