Array to pointer class template argument deduction works for template guide, but not for non template version, is that correct or bug?

  • A+
Category:Languages

I have class template with single type param and const char* type full specialization, simplified example below:

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 << "/"";     } }; 

In short - to print char strings like "abc" and all other values like (123) ("" vs ())

So, I added, as a replacement of additional partial specialization for all char[N] types a deduction guide:

template <std::size_t N> PrettyPrint(char(&)[N]) -> PrettyPrint<const char*>; //deduction guide 

Unfortunately it does not work:

 std::cout << PrettyPrint(7) << PrettyPrint("aaa") << PrettyPrint((const char*)"bbb"); 

(7)(aaa)"bbb"

Expected output:

(7)"aaa""bbb"

But, surprisingly, this works:

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"

So the questions:

  1. Is that correct (then why) or this is a bug in compilers (tested with gcc/clang - newest versions)
  2. If that is correct - then how to limit this template deduction guide to char only?

 


This is expected. A string literal has type const char[N]. Note the const. A const value cannot bind to a non-const reference, so your deduction guide is effectively not chosen and the primary template gets instantiated instead.

template <std::size_t N> PrettyPrint(const char(&)[N]) -> PrettyPrint<const char*>; 

Your second deduction guide works because here, T is deduced to be const char, which is perfectly fine.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: