|
-
June 8th, 2012, 06:35 AM
#1
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.
-
June 8th, 2012, 07:29 AM
#2
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 ) )
-
June 8th, 2012, 07:48 AM
#3
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 ... )
-
June 8th, 2012, 04:56 PM
#4
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.
-
June 9th, 2012, 03:16 AM
#5
Re: template specialization for char arrays
 Originally Posted by treuss
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 ).
 Originally Posted by treuss
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|