Explicit specialization of char []?

D

Dave Johansen

What is the syntax for doing an explicit specialization of a char []?
When I do an explicit specialization on "const char *" or "char *", it
doesn't handle an inline declared character array and calls the
default template method.

I'm using Visual C++ Express 2008 and below is an example of what I'm
trying to do.

Thanks,
Dave

#include <iostream>

template<typename T>
void func(const T &value)
{
std::cout << "T: " << value << std::endl;
}

template<>
void func<const char *>(const char * const &value)
{
std::cout << "CCS: ";
if (value != NULL)
std::cout << value << std::endl;
else
std::cout << "NULL" << std::endl;
}

int main(int argc, char *argv[])
{
const char *str1 = "testing1";
const char str2[] = "testing2";

func(str1);
func(str2);

return 0;
}
 
T

tonydee

What is the syntax for doing an explicit specialization of a char []?
When I do an explicit specialization on "const char *" or "char *", it
doesn't handle an inline declared character array and calls the
default template method.

I'm using Visual C++ Express 2008 and below is an example of what I'm
trying to do.

Thanks,
Dave

[ Code edited slightly for concision ]

#include <iostream>

template<typename T>
void func(const T &value)
{
    std::cout << "T: " << value << '\n';
}

template<>
void func<const char *>(const char * const &p)
{
    std::cout << "CCS: " << (p ? p : "NULL") << '\n';
}

int main()
{
    const char *str1 = "testing1";
    const char str2[] = "testing2";

    func(str1);
    func(str2);
}

Why not overload rather than specialise, ala:

template <int N>
void fn(const char a[N])
{
std::cout << "CCA: " << a << '\n';
}

Cheers,
Tony
 
D

Dave Johansen

What is the syntax for doing an explicit specialization of a char []?
When I do an explicit specialization on "const char *" or "char *", it
doesn't handle an inline declared character array and calls the
default template method.
I'm using Visual C++ Express 2008 and below is an example of what I'm
trying to do.
Thanks,
Dave

[ Code edited slightly for concision ]
#include <iostream>
template<typename T>
void func(const T &value)
{
    std::cout << "T: " << value << '\n';
}
template<>
void func<const char *>(const char * const &p)
{
    std::cout << "CCS: " << (p ? p : "NULL") << '\n';
}
int main()
{
    const char *str1 = "testing1";
    const char str2[] = "testing2";
    func(str1);
    func(str2);
}

Why not overload rather than specialise, ala:

template <int N>
void fn(const char a[N])
{
    std::cout << "CCA: " << a << '\n';

}

Cheers,
Tony

I'm not sure why, but that didn't work. However, it was the right idea
and the following did work:

void func(const char value[])
{
std::cout << "CA: " << value << std::endl;
}

If anyone knows how, I would still like to know how to do such an
explicit specialization, but thanks a ton for the help.
Dave
 
T

tonydee

template <int N>
void fn(const char a[N])
{
    std::cout << "CCA: " << a << '\n';

Cheers,
Tony

I'm not sure why, but that didn't work.

I should have used size_t... int might not be the size on your
system? Can't think of any other reason. What you've done (below) is
good if you don't need to know the array dimension...
However, it was the right idea
and the following did work:

void func(const char value[])
{
    std::cout << "CA: " << value << std::endl;

}

Cheers,
Tony
 
P

Paul Bibbings

Dave Johansen said:
What is the syntax for doing an explicit specialization of a char []?
When I do an explicit specialization on "const char *" or "char *", it
doesn't handle an inline declared character array and calls the
default template method.

For the purposes of template argument deduction an array of characters
is a different type from a pointer to a character array, so as a first
try this is always going to fail.
I'm using Visual C++ Express 2008 and below is an example of what I'm
trying to do.

Thanks,
Dave

#include <iostream>

template<typename T>
void func(const T &value)
{
std::cout << "T: " << value << std::endl;
}

template<>
void func<const char *>(const char * const &value)
{
std::cout << "CCS: ";
if (value != NULL)
std::cout << value << std::endl;
else
std::cout << "NULL" << std::endl;
}

// the following specialization will be chosen for str2
template<>
void func<char[9]>(const char (&value)[9])
{
std::cout << "CCA: ";
std::cout << value << std::endl;
}
int main(int argc, char *argv[])
{
const char *str1 = "testing1";
const char str2[] = "testing2";

func(str1);
func(str2);

return 0;
}

Note, however, that the array bounds is part of the type that is used to
match the new specialization. So, for example:

const char str3[] = "testing_3"; // char [10]
func(str3);

would again match only the primary template. Furthermore, IIRC, you
can't have a (cv) reference to an array of unknown bound, so it's not
possible to write the new specialization to match char arrays of
arbitrary size.

So, the bottom line is probably that you're better off following
tonydee's suggestion and providing an overload rather than a
specialization. (Unfortunately partial specialization of function
templates is not allowed, otherwise we might be tempted to write:

template<size_t N>
void func<char[N]>(const char (&value)[N]);

but the fact that we /can/ overload means that our inability to
partially specialize here is not much of a limitation after all.)

Regards

Paul Bibbings
 
S

SG

Dave Johansen said:
What is the syntax for doing an explicit specialization of a char []?

[...]
So, the bottom line is probably that you're better off following
tonydee's suggestion and providing an overload rather than a
specialization. (Unfortunately partial specialization of function
templates is not allowed, otherwise we might be tempted to write:

  template<size_t N>
  void func<char[N]>(const char (&value)[N]);

but the fact that we /can/ overload means that our inability to
partially specialize here is not much of a limitation after all.)

Let me point out an article that explains why overloading is generally
a better idea than specializing function templates:

http://www.gotw.ca/publications/mill17.htm

Cheers,
SG
 
D

Dave Johansen

template <int N>
void fn(const char a[N])
{
    std::cout << "CCA: " << a << '\n';
}
Cheers,
Tony
I'm not sure why, but that didn't work.

I should have used size_t... int might not be the size on your
system?  Can't think of any other reason.  What you've done (below) is
good if you don't need to know the array dimension...
However, it was the right idea
and the following did work:
void func(const char value[])
{
    std::cout << "CA: " << value << std::endl;

Cheers,
Tony

I'm not sure why, but I tried it with both int and size_t and neither
of them were called (the original template method was still called).
The other method (using the plain override with "const char value[]")
worked and seems to be accomplishing what I need.
Thanks,
Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,043
Members
48,769
Latest member
Clifft

Latest Threads

Top