Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Specializing template for const char*

20 views
Skip to first unread message

Juha Nieminen

unread,
Apr 30, 2015, 10:27:49 AM4/30/15
to
Consider this:

//------------------------------------------------------------------------
template<typename T> void foo(const T&) { std::printf("Generic\n"); }
template<> void foo(const char* const&) { std::printf("const char*\n"); }

int main()
{
foo(12);
foo("abc");
const char* str = "abc";
foo(str);
}
//------------------------------------------------------------------------

It prints:

Generic
Generic
const char*

What would be the best way to specialize a template for string literals?

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

simont

unread,
Apr 30, 2015, 11:24:58 AM4/30/15
to

On Thursday, April 30, 2015 at 3:27:49 PM UTC+1, Juha Nieminen wrote:
> Consider this:
>
> //------------------------------------------------------------------------
> template<typename T> void foo(const T&) { std::printf("Generic\n"); }
> template<> void foo(const char* const&) { std::printf("const char*\n"); }
>
> int main()
> {
> foo(12);
> foo("abc");
> const char* str = "abc";
> foo(str);
> }
> //------------------------------------------------------------------------
>
> It prints:
>
> Generic
> Generic
> const char*
>
> What would be the best way to specialize a template for string literals?

You could just stop trying to pass them by reference, so pointer decay works normally:

template<typename T> void foo(T) { std::printf("Generic\n"); }
template<> void foo(const char*) { std::printf("const char*\n"); }

or add

template<size_t N> void foo(const char (&)[N]) { std::printf("const char [%u]\n", N); }

if you want to differentiate between arrays and const char *.
I don't think there's a bulletproof way to distinguish between literals and
copy-initialized arrays, though.

Victor Bazarov

unread,
Apr 30, 2015, 11:25:23 AM4/30/15
to
On 4/30/2015 10:27 AM, Juha Nieminen wrote:
> Consider this:
>
> //------------------------------------------------------------------------
> template<typename T> void foo(const T&) { std::printf("Generic\n"); }
> template<> void foo(const char* const&) { std::printf("const char*\n"); }
>
> int main()
> {
> foo(12);
> foo("abc");
> const char* str = "abc";
> foo(str);
> }
> //------------------------------------------------------------------------
>
> It prints:
>
> Generic
> Generic
> const char*
>
> What would be the best way to specialize a template for string literals?

String literals are arrays of char, which do decay to pointers but not
for the purpose of type deduction. I think you should be able to make
this work:

template<typename T> void foo(const T&) { std::printf("Generic\n"); }
template<int n> void foo(const char(&)[n])
{ std::printf("array of const char\n"); }

int main()
{
foo(12);
foo("abc");
const char* str = "abc";
foo(str);
}

The problem, of course, is that literals of different lengths the
compiler will instantiate all different 'foo<n>' variations. You could
try to involve inheritance to unify those.

V
--
I do not respond to top-posted replies, please don't ask

guinne...@gmail.com

unread,
Apr 30, 2015, 11:31:42 AM4/30/15
to
On Thursday, 30 April 2015 15:27:49 UTC+1, Juha Nieminen wrote:
> Consider this:
>
> //------------------------------------------------------------------------
> template<typename T> void foo(const T&) { std::printf("Generic\n"); }
> template<> void foo(const char* const&) { std::printf("const char*\n"); }
>
> int main()
> {
> foo(12);
> foo("abc");
> const char* str = "abc";
> foo(str);
> }
> //------------------------------------------------------------------------
>
> It prints:
>
> Generic
> Generic
> const char*
>
> What would be the best way to specialize a template for string literals?

template<size_t N>
void foo(const char(&)[N]) { std::printf("const char(&)[]\n"); }
0 new messages