Предположим, у нас есть следующий код:
void ff(wchar_t*)
{
}
template<typename T>
void ffc(T&& a)
{
ff(std::forward<T>(a));
}
Почему звонок ff(0)
разрешено, но ffc(0)
не является?
В случае ffc(0)
Т будет выведен как ИНТ поскольку 0
целочисленный литерал, тип которого ИНТ и нет действительного неявного преобразования из int в wchar_t * даже без пересылки, поэтому следующий случай также не будет работать:
template<typename T>
void ffc_no_forward(T&& a)
{
ff(a);
}
тогда как в первом случае 0
является константой нулевого указателя и, следовательно, является вполне допустимым преобразованием в wchar_t *.
Мы можем видеть из проекта стандарта C ++ 14 (N4140
) раздел 4.10
Преобразование указателя [conv.ptr], что ИНТ с нулевым значением недостаточно, оно должно быть целочисленным литералом или должно иметь значение станд :: nullptr_t:
Константа нулевого указателя является целочисленным литералом (2.14.2) со значением ноль или значением типа std :: nullptr_t.
Константа нулевого указателя может быть преобразована в тип указателя; результатом является значение нулевого указателя этого типа
и отличается от любого другого значения указателя объекта или типа указателя на функцию. Такое преобразование
называется преобразованием нулевого указателя. […]
В C ++ 11 формулировка позволила интегральное постоянное выражение что оценивается до нуля, но в этом случае на самом деле не имеет значения, так как как T.C. указывает на то std::forward<T>()
не может быть константным выражением, поскольку параметр функции также не может быть константным выражением.
Других решений пока нет …