目前,我有一个这样定义的成员函数:
template<typename T> bool updateParameter(const std::string& name, const T& data);
具有指针的重载。
template<typename T> bool updateParameter(const std::string& name, T* data);
我希望能够像这样使用此功能:
int test = 20;
updateParameter<int>("name", 0);
updateParameter<int>("Referenced parameter", &test);
这样,我就可以拥有一个参数对象,该对象要么拥有它所代表的数据,要么指向一个用户拥有的成员。
现在,我的问题是当前设置MSVC隐式将“名称”的const 0转换为指针,因此最终调用了为指针设计的重载。我可以使用显式关键字,但是对于名称参数,我无法从const char []隐式转换为std :: string。有没有办法告诉编译器,MSVC和GCC某个字段不应该隐式转换,或者至少让它更喜欢const T&版本而不是T *版本?
这是一个VC ++错误。对于两个重载(char const[5]
=> std::string const&
),第一个参数的转换都是相同的。
对于第二个参数,虽然有两个不同的标准转换序列:对于T const&
-overload,该转换是一个身份转换-§13.3.3.1.4/ 1:
当引用类型的参数直接绑定(8.5.3)到参数表达式时,隐式转换序列是恒等转换,除非参数表达式的类型是参数类型[…]的派生类。
但是,转换0
为指针类型具有转换等级。第4.10条
甲空指针常数是整数字面(2.13.2)与零值或类型的prvalue
std::nullptr_t
。空指针常量可以转换为指针类型。结果是该类型的空指针值,并且可以与对象指针或函数指针类型的所有其他值区分开。这种转换称为空指针转换。
§13.3.3.1.1/ 3对此进行了相应的分类,同时还列出了我们的身份转换以及两者之间的关系:
最好的解决方法是简单地升级VC ++,因为最新版本会选择正确的过载(例如,与rextester的VC ++比较)。
另一个选择是data
通过引用代替第二次重载。§13.3.3.2/ 3.2.6可以防止歧义。或者根本不重载updateParameter
,而是提供第二个功能模板。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句