Предотвращение неявного преобразования некоторых аргументов в шаблонной функции-члене

В настоящее время у меня есть функция-член, определенная так:

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 *?

4

Решение

Это ошибка 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 и вообще предоставьте второй шаблон функции.

2

Другие решения


По вопросам рекламы [email protected]