功能超载以NULLPTR作为参数分辨率
Function overload resolution with nullptr as argument
考虑以下代码。尽管fun
的两个过载都接受指针,但将nullptr
传递给fun
并不会导致任何汇编错误。而非常相似的功能bun
无法编译。当我使用typeid(i).name()
打印参数i
的类型时(修改代码后,只是为了打印此版本) 我获得相同的类型,只需int*
即可。解决fun
情况下歧义性但bun
失败的规则是什么?预先感谢!
#include <iostream>
struct Foo {
int sth;
};
template< class U>
void fun(decltype(U::sth)* i){
std::cout << "1" << std::endl;
}
template< class U>
void fun(U* i){
std::cout << "2" << std::endl;
}
void bun(decltype(Foo::sth)* i){
std::cout << "3" << std::endl;
}
void bun(Foo* i){
std::cout << "4" << std::endl;
}
int main ( )
{
fun<Foo>(nullptr);
// bun(nullptr); --> call of overloaded 'bun(std::nullptr_t)' is ambiguous
return 0;
}
-----------------------
output : 1
好吧,实际上,GCC接受您的代码,但Clang不接受。因此,起初并不明显是否呼叫是模棱两可的。
您询问在fun
情况下解决什么规则;海湾合作委员会显然认为有这样的规则。我认为GCC应用的规则是[over.match.best]/1.7的规则,它优先于更专业函数模板而不是较少专业的模板。
确定哪种功能模板比[temp.func.order]中描述的另一个功能模板更专业,并在此SO答案中彻底解释了。但是,您会注意到,当尝试将此过程应用于fun
的两个过载时,我们会遇到一个问题,即需要在第一个过载中替换为U
的唯一合成类型,需要有一个成员命名为sth
,并且未指定该成员的性质,尽管对于人类来说,即使第二个fun
过载中的扣除都必须成功,无论sth
的类型是什么,但编译器可能无法证明这一点。
这是CWG1157。由于此问题仍然没有提议的解决方案,因此我对WG21是否打算成功解决此问题。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C 中函数参数/参数的分辨率
- 当参数不同时,重载分辨率不会选择模板
- 功能超载以NULLPTR作为参数分辨率
- 两个功能的过载分辨率采用参数包
- 提高绑定可变参数过载分辨率
- 如何获得可变参数模板功能的正确分辨率而不会太冗长
- 可变参数模板类型特征分辨率
- 使用SFINAE分辨率区分普通模板参数和模板模板参数的技术