目前我有一个成员函数定义如下:
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隐式地将“name”的const 0转换为指针,因此它最终调用为指针设计的重载.我可以使用explicit关键字,但是我无法从name char []到std :: string的name参数进行隐式转换.
有没有办法告诉编译器,MSVC和GCC某个字段不应该被隐式转换,或者至少是因为它更喜欢const T&版本超过T *版本?
最佳答案 这是一个VC bug.第一个参数的转换对于两个重载都是相同的(char const [5] => std :: string const&).
对于第二个参数,有两个不同的标准转换序列:对于T const& -overload,转换是一个标识转换 – §13.3.3.1.4/ 1:
When a parameter of reference type binds directly (8.5.3) to an
argument expression, the implicit conversion sequence is the identity
conversion, unless the argument expression has a type that is a
derived class of the parameter type […]
但是,将0转换为指针类型具有转换等级. §4.10去
A null pointer constant is an integer literal (2.13.2) with value zero
or a prvalue of typestd::nullptr_t
. A null pointer constant can be
converted to a pointer type; the result is the null pointer value of
that type and is distinguishable from every other value of object
pointer or function pointer type. Such a conversion
is called a null pointer conversion.
§13.3.3.1.1/ 3对此进行了分类,同时也列出了我们的身份转换以及两者如何相关:
最好的解决方法是简单地升级VC,因为最新版本选择了正确的重载(例如与rextester’s VC++比较).
另一种选择是通过引用获取数据而不是第二次重载. §13.3.3.2/ 3.2.6将阻止歧义.或者根本不要重载updateParameter,而是提供第二个函数模板.