Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ templates: How to conditionally compile different code based on data type?

Tags:

c++

templates

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

like image 338
George T. Avatar asked Jun 05 '17 14:06

George T.


People also ask

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

Can templates be used for user defined data types?

Template in C++is a feature. We write code once and use it for any data type including user defined data types.

Can you use templates in C?

The main type of templates that can be implemented in C are static templates. Static templates are created at compile time and do not perform runtime checks on sizes, because they shift that responsibility to the compiler.

How are templates compile in C++?

Template compilation requires the C++ compiler to do more than traditional UNIX compilers have done. The C++ compiler must generate object code for template instances on an as-needed basis. It might share template instances among separate compilations using a template repository.


1 Answers

Use std::char_traits<CharT>.

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:

  • I changed the type of parameter 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.
  • I changed the return type to 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.
like image 59
zett42 Avatar answered Oct 06 '22 17:10

zett42