В настоящее время у меня есть функция-член, определенная так:
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 «name» в указатель, поэтому в итоге вызывается перегрузка, предназначенная для указателей. Я могу использовать явное ключевое слово, но тогда я не могу получить неявное преобразование из const char [] в std :: string для параметра name.
Есть ли способ сообщить компилятору, MSVC и GCC, что определенное поле не должно быть неявно преобразовано или, по крайней мере, для него предпочтительнее const T& версия над версией T *?
Это ошибка VC ++. Преобразование первого аргумента идентично для обеих перегрузок (char const[5]
=> std::string const&
).
Для второго аргумента есть две различные стандартные последовательности преобразования: T const&
— перегрузка, преобразование является преобразованием идентичности — §13.3.3.1.4 / 1:
Когда параметр ссылочного типа привязывается напрямую (8.5.3) к
выражение аргумента, неявная последовательность преобразования является тождеством
преобразование, если выражение аргумента не имеет тип, который является
производный класс типа параметра […]
Тем не менее, преобразование 0
Тип указателя имеет Преобразование ранга. §4.10 идет
константа нулевого указателя целочисленный литерал (2.13.2) со значением ноль
или тип значенияstd::nullptr_t
, Константа нулевого указателя может быть
преобразован в тип указателя; результатом является значение нулевого указателя из
этот тип и отличается от любого другого значения объекта
указатель или тип указателя функции. Такое преобразование
называется преобразование нулевого указателя.
И §13.3.3.1.1 / 3 классифицирует это соответственно, в то же время перечисляя наше преобразование идентичности и как оба связаны:
Лучший обходной путь — просто обновить VC ++, так как последние версии выбирают правильную перегрузку (например, сравнивают с VC ++ ректестера).
Другой вариант — взять data
вместо этого для вашей второй перегрузки. Неопределенности будут предотвращены согласно §13.3.3.2 / 3.2.6. Или просто не перегружайте updateParameter
и вообще предоставьте второй шаблон функции.