gpt4 book ai didi

c++ - 具有统一初始化的自动扩展为意外类型

转载 作者:太空狗 更新时间:2023-10-29 19:53:07 24 4
gpt4 key购买 nike

考虑这个用 GCC 4.7.2 编译的短程序 g++ -std=c++11 test.cc

#include <memory>
#include <queue>

struct type{
type(int a) : v(a) {}
int v;
};

typedef std::shared_ptr<type> type_ptr;

int main(){
int value = 3;
std::queue<type_ptr> queue;
auto ptr{std::make_shared<type>(value)};
queue.push(ptr);
}

编译器输出以下错误:

src/test.cc: In function ‘int main()’:
src/test.cc:15:17: error: no matching function for call to ‘std::queue<std::shared_ptr<type> >::push(std::initializer_list<std::shared_ptr<type> >&)’
src/test.cc:15:17: note: candidates are:
In file included from /usr/include/c++/4.7/queue:65:0,
from src/test.cc:2:
/usr/include/c++/4.7/bits/stl_queue.h:211:7: note: void std::queue<_Tp, _Sequence>::push(const value_type&) [with _Tp = std::shared_ptr<type>; _Sequence = std::deque<std::shared_ptr<type>, std::allocator<std::shared_ptr<type> > >; std::queue<_Tp, _Sequence>::value_type = std::shared_ptr<type>]
/usr/include/c++/4.7/bits/stl_queue.h:211:7: note: no known conversion for argument 1 from ‘std::initializer_list<std::shared_ptr<type> >’ to ‘const value_type& {aka const std::shared_ptr<type>&}’
/usr/include/c++/4.7/bits/stl_queue.h:216:7: note: void std::queue<_Tp, _Sequence>::push(std::queue<_Tp, _Sequence>::value_type&&) [with _Tp = std::shared_ptr<type>; _Sequence = std::deque<std::shared_ptr<type>, std::allocator<std::shared_ptr<type> > >; std::queue<_Tp, _Sequence>::value_type = std::shared_ptr<type>]
/usr/include/c++/4.7/bits/stl_queue.h:216:7: note: no known conversion for argument 1 from ‘std::initializer_list<std::shared_ptr<type> >’ to ‘std::queue<std::shared_ptr<type> >::value_type&& {aka std::shared_ptr<type>&&}’

表示 auto 类型扩展为初始化列表而不是 std::shared_ptr<type> ;实际上替换了 {...}= ...使代码编译为自动扩展为正确的类型。

我有点惊讶这个看似显而易见的用例未能达到预期的结果。特别是当我记得新的括号初始化语法被吹捧为初始化问题的最终解决方案时。

所以我的问题是:这是标准中的意图吗?还是疏忽甚至是 gcc 错误?还是我想错了?

最佳答案

正如 Xeo 在他的评论中所说,这是标准行为。 7.1.6.4 自动说明符 [dcl.spec.auto] 第 6 段指定:

Once the type of a declarator-id has been determined according to 8.3, the type of the declared variable using the declarator-id is determined from the type of its initializer using the rules for template argument deduction. Let T be the type that has been determined for a variable identifier d. Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>. The type deduced for the variable d is then the deduced A determined using the rules of template argument deduction from a function call (14.8.2.1), where P is a function template parameter type and the initializer for d is the corresponding argument. If the deduction fails, the declaration is ill-formed.

它也被广泛鄙视 - 有一个 proposal under review by the committee更改 C++14 的行为。 C++14 对广义 lambda 捕获的支持 exacerbates the problem .

更新:在厄巴纳(参见 N4251 WG21 2014-11 Urbana Minutes 中的 CWG 动议 16),委员会申请了 N3922 New Rules for auto deduction from braced-init-list到 C++17 工作论文。他们决定修复允许 auto 的特殊情况推断出一个initializer_list通过添加另一个 特例。 auto copy-list-initialization 的工作方式相同,但direct-list-initialization 来自 braced-init-list 和单个元素auto直接从该元素推导出来。来自多元素 braced-init-listdirect-list-initialization 现在格式错误。

这意味着给定

auto x = {42};

x类型为 std::initializer_list<int> , 但在

auto x{42};

x是一个 int .

关于c++ - 具有统一初始化的自动扩展为意外类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17551316/

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