gpt4 book ai didi

c++ - Clang 或 GCC 拒绝/接受此 CTAD 代码是否正确?

转载 作者:行者123 更新时间:2023-12-04 11:06:50 25 4
gpt4 key购买 nike

Clang 和 GCC disagree接受此代码。
什么是标准要求的行为?

#include <utility>
#include <iostream>
#include <vector>

int main()
{
std::vector pairs = {std::pair{1,11},{2,22}, {3,33}};
for (const auto& p: pairs) {
std::cout << p.second << std::endl;
}
}
注意:我知道这是 C++,所以标准可能是模糊的,但我认为一种行为是正确的。

最佳答案

CTAD 的过程主要由 [over.match.class.deduct] 定义。 .从广义上讲,重载集是该类型的所有可访问构造函数,以及任何推导指南。并且根据此规则解决重载集:

Initialization and overload resolution are performed as described in [dcl.init] and [over.match.ctor], [over.match.copy], or [over.match.list] (as appropriate for the type of initialization performed)


由于“执行的初始化类型”肯定是列表初始化,我们继续 [over.match.list] .我们在哪里得到这个臭名昭著的项目符号列表:
  • Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list consists of the initializer list as a single argument.

  • If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.


这告诉我们 initializer-list constructors被优先考虑;他们以一种非常具体的方式(即构建 std::initializer_list 并将其作为参数传递)获得了重载解决方案的第一次破解。但是,Clang 给出了一个明显的错误:
note: candidate function template not viable: requires at most 2 arguments, but 3 were provided
vector(initializer_list<value_type> __l,

也就是说,它试图调用该构造函数,就好像“参数列表由初始化列表的元素组成”一样。这表明 Clang 在通过 CTAD 进行列表初始化时跳过了第一个要点。在括号初始化列表周围添加括号“修复”了问题的事实也表明这就是正在发生的事情。
奇怪的是,它适用于简单的类型,比如整数的初始化列表。如果您将每个成员明确命名为 pair,它就会起作用。 .和 Clang 可以 auto -推断 initializer_list的类型制作人 {std::pair{1,11}, {2,22}, {3,33}}正好。所以这个错误似乎非常具体。

关于c++ - Clang 或 GCC 拒绝/接受此 CTAD 代码是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66124794/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com