如果函数参数包的推导出现在非推导上下文中,会发生什么?

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

当前的标准草案包含此内容(参见本段的最后一句): “当函数参数包出现在非推导上下文 ([temp.deduct.type]) 中时,永远不会推导该包的类型。”

现在,包永远不会被推导是什么意思?如果用户没有指定pack的值,也没有推导出来,难道不是编译失败吗?

当前的编译器处理这种情况,将包定义为空。

这是草稿中的一个精简的示例

template<class T1, class ... Types> void g1(Types ..., T1);

void h(int x, float& y) {
  const int z = x;
  g1(x, y, z);                  // error: Types is not deduced
}

这无法编译。但是,如果我将示例修改为仅使用 1 个参数,则该示例将编译:

template<class T1, class ... Types> void g1(Types ..., T1);

void h(int x, float& y) {
  const int z = x;
  g1(x); // compiles
}

标准中是否有任何内容规定在这种情况下,包装应该是空的?为什么这不是编译错误?

我明白,在后一个例子中,很明显

Types
是空的,因为这是使编译成功的唯一方法。但是,在前面的示例中,“x, y”部分对应于
Types
也应该是显而易见的。我知道,
Types
没有被推导出来,所以这个例子不应该编译。那么第二个例子如何编译呢?
Types
在这里也没有推导,所以如果我们考虑“错误:类型未推导”注释(这使得示例无法编译),这也应该使示例格式错误。

开头引用的引用听起来不应该像:“当函数参数包出现在非推导上下文([temp.deduct.type])中时,该包被推导为空。” (这当然看起来有点奇怪,因为它定义了在非推导上下文中推导的东西,但这不是这里发生的事情吗?)

注意:之前也有过类似的问题。但我认为我的问题更明确,并且包含当前草案中的引用(当时没有引用该引用),所以我认为最好提出一个新问题。

c++ language-lawyer c++26
1个回答
0
投票

当函数参数包处于非推导上下文中时,这意味着编译器无法根据提供的参数确定该包的类型。这种情况下,如果没有推导pack,也不会导致编译错误;相反,它被视为空包。

在第一个使用

g1(x, y, z)
的示例中,编译器无法推断
Types
的类型,因为它处于非推导上下文中(由于包后存在
T1
)。这会导致编译错误,因为它需要为
Types
推导出至少一种类型。

g1(x)
的第二个示例中,
Types
没有参数,因此很明显
Types
必须为空。编译器允许这样做,因为它可以从逻辑上得出结论:没有类型可以推断。

该标准没有明确指出在此上下文中包应该为空,但暗示如果无法推断出任何类型,则包将被视为空,这使得代码可以无错误地编译。因此,虽然看起来可能令人困惑,但语言的规则允许这种行为,并且它与编译器处理这些情况的方式一致。

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