jac*_*k X 3 c++ language-lawyer
考虑一下这个例子
\n#include <iostream>\n\nstruct A{\n void* operator new(std::size_t N, std::align_val_t){ // #1\n return malloc(sizeof(char)* N);\n }\n};\nint main(){\n auto ptr = new A; // #2\n}\nRun Code Online (Sandbox Code Playgroud)\nGCC 和 Clang 都抱怨说
\n<source>:9:17: error: no matching function for call to \'operator new\'\n auto ptr = new A;\n ^\n<source>:4:11: note: candidate function not viable: requires 2 arguments, but 1 was provided\n void* operator new(std::size_t N, std::align_val_t){\n ^\n1 error generated.\nRun Code Online (Sandbox Code Playgroud)\n然而,[expr.new] p19 说
\n\n\n重载解析是在通过组装参数列表创建的函数调用上执行的。\n第一个参数是请求的空间量,类型为 std\xe2\x80\x8b::\xe2\x80\x8bsize_\xc2\xadt。\ n如果分配对象的类型具有新扩展对齐方式,则下一个参数是类型的对齐方式,并且类型为 std\xe2\x80\x8b::\xe2\x80\x8balign_\xc2\xadval_\xc2\xadt .\n如果使用新放置语法,则其表达式列表中的初始值设定项子句是后续参数。如果没有找到匹配的函数那么
\n\n\n\n
\n- 如果分配的对象类型具有新扩展对齐方式,则从参数列表中删除对齐方式参数;
\n- 否则,作为类型对齐且类型为 std\xe2\x80\x8b::\xe2\x80\x8balign_\xc2\xadval_\xc2\xadt 的参数将立即添加到第一个参数之后的参数列表中;
\n然后再次进行重载决策。
\n
在新表达式中调用的分配函数的找到候选者#2是#1。第一次,组装参数列表为sizeof(A),无法构成#1匹配函数,则根据规则,组装参数列表为sizeof(A),std::align_val_t(alignof(A)),可构成#1匹配函数。另外,这是一个典型的例子记录在[expr.new] p20中记录的一个典型例子
\n\n\n
new T导致以下调用之一:\n\n\n
\n- 运算符 new(sizeof(T))
\n- 运算符 new(sizeof(T), std::align_val_t(alignof(T)))
\n
为什么 GCC 和 Clang 拒绝这个例子?这是GCC和Clang的缺陷吗?或者,我是否误解了什么?
\n目前唯一实现CWG 2282 的主要编译器是MSVC。我不知道 GCC 或 clang 目前有任何努力或功能请求。
另外,我不认为__cpp_aligned_newCWG 2282 的功能测试宏已更新,因此您需要使用老式编译器版本检查来确定该功能是否可用。
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |