Explicit specialization of char []?

Discussion in 'C++' started by Dave Johansen, Feb 24, 2010.

  1. 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;
    }
     
    Dave Johansen, Feb 24, 2010
    #1
    1. Advertising

  2. Dave Johansen

    tonydee Guest

    On Feb 24, 11:21 am, Dave Johansen <> wrote:
    > 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
     
    tonydee, Feb 24, 2010
    #2
    1. Advertising

  3. On Feb 23, 8:05 pm, tonydee <> wrote:
    > On Feb 24, 11:21 am, Dave Johansen <> wrote:
    >
    >
    >
    > > 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
     
    Dave Johansen, Feb 24, 2010
    #3
  4. Dave Johansen

    tonydee Guest

    On Feb 24, 1:28 pm, Dave Johansen <> wrote:
    > On Feb 23, 8:05 pm, tonydee <> wrote:
    > > 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
     
    tonydee, Feb 24, 2010
    #4
  5. Dave Johansen <davejohansen@...com> writes:

    > 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
     
    Paul Bibbings, Feb 24, 2010
    #5
  6. Dave Johansen

    SG Guest

    On 24 Feb., 11:28, Paul Bibbings wrote:
    > Dave Johansen <davejohansen@...com> writes:
    > > 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
     
    SG, Feb 24, 2010
    #6
  7. On Feb 23, 11:11 pm, tonydee <> wrote:
    > On Feb 24, 1:28 pm, Dave Johansen <> wrote:
    >
    > > On Feb 23, 8:05 pm, tonydee <> wrote:
    > > > 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
     
    Dave Johansen, Feb 24, 2010
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andriy Shnyr
    Replies:
    3
    Views:
    773
    Larry Evans
    Dec 4, 2003
  2. J.T. Conklin
    Replies:
    1
    Views:
    466
    David Hilsee
    Aug 11, 2004
  3. Andy
    Replies:
    5
    Views:
    526
    Shezan Baig
    Jan 30, 2005
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,151
    Ian Collins
    May 9, 2006
  5. Replies:
    1
    Views:
    617
    Salt_Peter
    Dec 25, 2006
Loading...

Share This Page