if 语句内可变参数模板的扩展

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

我尝试编写一个函数来检查“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) && ...) )

我参考的问题: 用于检查变量是否等于可变参数之一的可变宏

使用 C++17 折叠表达式测试所有元素是否相等

那么,为什么没有额外的括号就不起作用呢?这与表达式的解包方式有关吗?

upd:我发现据说更好的方法是写

if(((received != allowed) && ...) == false) {

有人可以解释一下如何以及为什么这样更好(如果有的话)?

c++ compiler-errors variadic-templates
1个回答
0
投票

你问:

为什么没有额外的括号就不起作用?

无聊的答案是,这就是 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
的非可选部分。

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