Reputation: 119
Here's a small example that illustrates the essence of my question:
#include <iostream>
using namespace std ;
typedef char achar_t ;
template < class T > class STRING
{
public:
T * memory ;
int size ;
int capacity ;
public:
STRING() {
size = 0 ;
capacity = 128 ;
memory = ( T *) malloc( capacity * sizeof(T) ) ;
}
const STRING& operator=( T * buf) {
if ( typeid(T) == typeid(char) )
strcpy( memory, buf ) ;
else
wcscpy( memory, buf ) ;
return *this ;
}
} ;
void main()
{
STRING<achar_t> a ;
STRING<wchar_t> w ;
a = "a_test" ;
w = L"w_test" ;
cout << " a = " << a.memory << endl ;
cout << " w = " << w.memory << endl ;
}
Can some one please help me compile the above? That is somehow compile either with strcpy() or wcscpy() based on the type of the object i am using.
thank you
Upvotes: 5
Views: 2419
Reputation: 27806
You can replace strcpy()
and wcscpy()
by combining the static methods std::char_traits::length()
and std::char_traits::copy()
. This will also make your code more generic because std::char_traits
has specializations for char16_t
and char32_t
.
STRING& operator=( T const * buf) {
// TODO: Make sure that buffer size for 'memory' is large enough.
// You propably also want to assign the 'size' member.
auto len = std::char_traits< T >::length( buf );
std::char_traits< T >::copy( memory, buf, len );
return *this ;
}
Side notes:
buf
to T const*
because it is not legal to assign a string literal to a pointer that points to non-const data. We only need read access to the data pointed to by buf
.STRING&
because that's the way how the assignment operator usually is declared. The method must be non-const so there is no point in restricting the return type to a constant reference. Upvotes: 7
Reputation: 18441
If you are using C++17, you can use if constexpr
also:
if constexpr (std::is_same<char, T>::value)
strcpy( memory, buf );
else
wcscpy( memory, buf );
The branch that fails the condition will not be compiled for the given template instantiation.
Upvotes: 6
Reputation: 74
You can use template specialization.
template<typename T>
class STRING {
public:
T * memory ;
int size ;
int capacity ;
public:
STRING() {
size = 0 ;
capacity = 128 ;
memory = ( T *) malloc( capacity * sizeof(T) ) ;
}
STRING const & operator=(T * buf);
};
And you define a specialization for the type you want
template<> STRING<achar_t> const & STRING<achar_t>::operator=(achar_t * buf)
{
strcpy(memory, buf );
return *this;
}
template<> STRING<wchar_t> const & STRING<wchar_t>::operator=(wchar_t * buf)
{
wcscpy( memory, buf );
return *this;
}
I didn't test this code but you can find more information here http://en.cppreference.com/w/cpp/language/template_specialization
Upvotes: 0