CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    template specialization for char arrays

    Hi,

    I'm trying to get template specializations working for char * as well as for char[]. I.e. in the following code the last test does not use the specialization and fails:
    Code:
    #include <string>
    #include <iostream>
    #include <cstring>
    
    template<typename T1, typename T2>
    bool compare(const T1& lhs, const T2& rhs)
    {
            std::cout << "DEBUG: Using generic template\n";
            return lhs == rhs;
    }
    
    template<>
    bool compare<const char*, const char*>(const char * const& lhs, const char * const& rhs)
    {
            std::cout << "DEBUG: Using template specialization\n";
            return strcmp(lhs, rhs) == 0;
    }
    
    int main()
    {
            std::string test = "abc";
            if (compare(test, test))
            {
                    std::cout << "Test 1 succeeded\n";
            }
            if (compare(test.c_str(), test.c_str()))
            {
                    std::cout << "Test 2 succeeded\n";
            }
            if (compare(test.c_str(), "abc"))
            {
                    std::cout << "Test 3 succeeded\n";
            }
    
            return 0;
    }
    Any hint, what I'm doing wrong?
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  2. #2
    Join Date
    Oct 2008
    Posts
    1,456

    Re: template specialization for char arrays

    why don't you use overload instead of specialization ? ( say, just bool compare( const char* lhs, const char* rhs ) )

  3. #3
    Join Date
    Oct 2008
    Posts
    1,456

    Re: template specialization for char arrays

    BTW, if for some reason you cannot just overload it, I'd prefer some flavor of type dispatching to specialization, for example:

    Code:
    #include <string>
    #include <iostream>
    #include <cstring>
    #include <type_traits>
    
    template<typename T1, typename T2>
    struct compare_trait
    {
    	static bool result( const T1& l, const T2& r ) { return l == r; }
    };
    
    template<>
    struct compare_trait< const char*, const char* >
    {
    	static bool result( const char* l, const char* r ) { return strcmp(l, r) == 0; }
    };
    
    template<typename T1, typename T2>
    bool compare(const T1& lhs, const T2& rhs)
    {
        return compare_trait<
    			typename std::decay<T1>::type,
    			typename std::decay<T2>::type
    		>::result( lhs, rhs );
    }
    
    int main()
    {
            std::string test = "abc";
            if (compare(test, test))
            {
                    std::cout << "Test 1 succeeded\n";
            }
            if (compare(test.c_str(), test.c_str()))
            {
                    std::cout << "Test 2 succeeded\n";
            }
            if (compare(test.c_str(), "abc"))
            {
                    std::cout << "Test 3 succeeded\n";
            }
    
            return 0;
    }
    IMHO it's cleaner, simpler and more flexible ( you can do all sort of metaprogramming on T1, T2 ... )

  4. #4
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: template specialization for char arrays

    Thanks Superbonzo for both posts.

    Overloading indeed solves my problem, but iirc, combining overloading and template specialization causes some difficult to predict behaviour (depending on the order of decalaration of the functions).

    The idea with the traits class looks great and more generic. I'm a bit confused though: Why does std:ecay::type do the array to pointer conversion when the traits class in your code is instantiated, but when trying to call a function it does not happen. In other words, why does the below code not compile?
    Code:
    #include <string>
    #include <iostream>
    #include <cstring>
    #include <type_traits>
    
    template<typename T1, typename T2>
    bool compare(const T1& lhs, const T2& rhs)
    {
            std::cout << "DEBUG: Using generic template\n";
            return lhs == rhs;
    }
    
    template<>
    bool compare<const char*, const char*>(const char * const& lhs, const char * const& rhs)
    {
            std::cout << "DEBUG: Using template specialization\n";
            return strcmp(lhs, rhs) == 0;
    }
    
    template<typename T1, typename T2>
    bool is_equal(const T1& lhs, const T2& rhs)
    {
            return compare<typename std::decay<T1>::type, typename std::decay<T2>::type>( lhs, rhs );
    }
    
    int main()
    {
            std::string test = "abc";
            if (is_equal(test, test))
            {
                    std::cout << "Test 1 succeeded\n";
            }
            if (is_equal(test.c_str(), test.c_str()))
            {
                    std::cout << "Test 2 succeeded\n";
            }
            if (is_equal(test.c_str(), "abc"))
            {
                    std::cout << "Test 3 succeeded\n";
            }
    
            return 0;
    }
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: template specialization for char arrays

    Quote Originally Posted by treuss View Post
    iirc, combining overloading and template specialization causes some difficult to predict behaviour (depending on the order of decalaration of the functions).
    you're right, but my point was to not use specialization at all ( being inflexible and interacting badly with overloads, that you may always need in the future ), just use overloads, eventually templated, eventually bounded through SFINAE. That said, if the overload resolution is especially complex or must be controlled beforehand, type dispatching is a better choice, IMHO ( one can use trait classes, tag disptaching, metafunction tag dispatching, etc... according to the wanted design complexity ).

    Quote Originally Posted by treuss View Post
    In other words, why does the below code not compile?
    well, I see nothing wrong with that code; BTW, note that it does compile and runs correctly in vc2010 ...

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured