how to distinguish between const char* and const char[N]

Hi! is there a (possibly boost powered) way of distinguishing between const char* and const char[N]? e.g. const char* foo = "foo"; bar(foo); bar("foo"); The second call to bar should extract the length at compile time, e.g. template <size_t length> void bar(const char (&data)[length]) {...} The problem is that in the presence of the first variant (void bar(const char*)) the second variant does not get called. -Jochen

At Mon, 20 Dec 2010 00:21:26 +0100, Jochen Wilhelmy wrote:
Hi!
is there a (possibly boost powered) way of distinguishing between const char* and const char[N]?
e.g.
const char* foo = "foo"; bar(foo); bar("foo");
The second call to bar should extract the length at compile time, e.g.
template <size_t length> void bar(const char (&data)[length]) {...}
The problem is that in the presence of the first variant (void bar(const char*)) the second variant does not get called.
// untested! #include <boost/enable_if.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/remove_pointer.hpp> typedef whatever1 returntype1; typedef whatever2 returntype2; template <class T> typename boost::enable_if< boost::is_same< const typename boost::remove_pointer<T>::type , char const >, returntype1>::type int bar(T); template <unsigned N> returntype2 bar(char const(&)[N]); HTH, -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On 12/19/2010 3:21 PM, Jochen Wilhelmy wrote:
Hi!
is there a (possibly boost powered) way of distinguishing between const char* and const char[N]?
e.g.
const char* foo = "foo"; bar(foo); bar("foo");
The second call to bar should extract the length at compile time, e.g.
template <size_t length> void bar(const char (&data)[length]) {...}
The problem is that in the presence of the first variant (void bar(const char*)) the second variant does not get called.
-Jochen
In addition to Dave's solution, it looks like if your overloads look like void bar(char const *&); // note the & template< std::size_t N > void bar(char const (&)[N]); then the latter will be selected when passed a string literal. Seems to work on MSVC9 anyway... - Jeff

On 12/19/2010 4:43 PM, Jeffrey Lee Hellrung, Jr. wrote:
On 12/19/2010 3:21 PM, Jochen Wilhelmy wrote:
Hi!
is there a (possibly boost powered) way of distinguishing between const char* and const char[N]? [...] In addition to Dave's solution, it looks like if your overloads look like
void bar(char const *&); // note the & template< std::size_t N > void bar(char const (&)[N]);
then the latter will be selected when passed a string literal. Seems to work on MSVC9 anyway...
- Jeff
Never mind, forgot a "const" qualifier in the first overload (should be "char const * const &" to preserve desired behavior), which then doesn't solve the problem... Sorry for the spam, - Jeff

On Dec 19, 2010, at 4:43 PM, Jeffrey Lee Hellrung, Jr. wrote:
The second call to bar should extract the length at compile time, e.g.
template <size_t length> void bar(const char (&data)[length]) {...}
The problem is that in the presence of the first variant (void bar(const char*)) the second variant does not get called.
-Jochen
In addition to Dave's solution, it looks like if your overloads look like
void bar(char const *&); // note the & template< std::size_t N > void bar(char const (&)[N]);
then the latter will be selected when passed a string literal. Seems to work on MSVC9 anyway...
The Sun Solaris compiler doesn't seem to handle the "char const (&)[N]" syntax. I had to work around it in Boost.Array (look in array.hpp starting about line 349) Just a data point for you. -- Marshall
participants (4)
-
Dave Abrahams
-
Jeffrey Lee Hellrung, Jr.
-
Jochen Wilhelmy
-
Marshall Clow