У меня есть шаблон класса с параметром одного типа и полной специализацией типа const char*
, упрощенный пример ниже:
template <typename T>
struct PrettyPrint {
PrettyPrint(const T& value) : value(value) {}
const T& value;
friend std::ostream& operator << (std::ostream& os, const PrettyPrint& pp) {
return os << "(" << pp.value << ")";
}
};
template <>
struct PrettyPrint<const char*> {
PrettyPrint(const char* value) : value(value) {}
const char* value;
friend std::ostream& operator << (std::ostream& os, const PrettyPrint& pp) {
return os << "\"" << pp.value << "\"";
}
};
Вкратце - для печати строк символов, таких как "abc"
и всех других значений, таких как (123)
(""
против ()
)
Итак, я добавил в качестве замены дополнительной частичной специализации для всех типов char[N]
руководство по выводам:
template <std::size_t N>
PrettyPrint(char(&)[N]) -> PrettyPrint<const char*>; //deduction guide
К сожалению, это такне работает:
std::cout << PrettyPrint(7) << PrettyPrint("aaa") << PrettyPrint((const char*)"bbb");
(7) (aaa) "bbb"
Ожидаемый результат:
(7) "aaa"" bbb "
Но, как ни странно, это работает:
template <typename T, std::size_t N>
PrettyPrinter(T(&)[N]) -> PrettyPrinter<const T*>; //deduction guide
std::cout << PrettyPrint(7) << PrettyPrint("aaa") << PrettyPrint((const char*)"bbb");
(7)" aaa "" bbb "
Итак, вопросы:
- Это правильно (тогда почему) или это ошибка в компиляторах (протестировано с gcc / clang - новейшие версии)
- Если это правильно - то какограничить этот шаблон руководства вычетом только
char
?