Template Instantiation

This is a discussion on Template Instantiation within the C++ Programming forums, part of the General Programming Boards category; Code: basic_string<T> lol, rofl; if(typeid(T) == typeid(wchar_t)) { lol = L"Time", rofl = L"Name"; } if(typeid(T) == typeid(char)) { lol ...

  1. #1
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465

    Template Instantiation

    Code:
    	basic_string<T> lol, rofl;
    
    	if(typeid(T) == typeid(wchar_t))
    	{
    		lol = L"Time", rofl = L"Name";
    	}
    
    	if(typeid(T) == typeid(char))
    	{
    		lol = "Time", rofl = "Name";
    	}
    This gives compile error

    error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const char [5]' (or there is no acceptable conversion)

    You know what I'm trying to do, wide string if the instatiation is unicode, narrowed if not. How do I express myself?

    ╔╗╔╦══╦╗╔╦══╦╗
    ║╚╝║╔╗║╚╝║╔╗║║
    ║╔╗║╠╣║╔╗║╠╣╠╣
    ╚╝╚╩╝╚╩╝╚╩╝╚╩╝

    codez http://code.google.com/p/zxcvbn/

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,899
    No workie that way. For strings, you can use _T macro (or TEXT).
    lol = _T("Time"), rofl = _T("Name");
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    Unfortunately the _T or _TEXT macros won't work if the type T is not dependent on whether UNICODE is defined.

    One possible solution is to have a templated function that has a specialization for one or more types T that you wish to make a special case for.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,528
    And _T, etc are non-portable.

    The reason for the compiler error is that lol and rofl are of type basic_string<char> (essentially a raw std::string), which supports an assignment operator that accepts a char * but not an assignment operator that accects a wchar_t * argument. For that case, those variables need to be of type basic_string<wchar_t>.

    You need to make up your mind which type you want your variables to be.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,691
    I wish folks would just stop using TCHAR's.....

    Are you actually writting code that needs to run on Windows 95? If not, just use wchar_t and be done with it.

    gg

  6. #6
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    I am writing a program to convert make m3u/pls out of the text files itunes exports. It doesn't export regular playlists.

    The text file exported is in uniucode but I have some serious froblems with the wifstream so I was just converting it to ascii. I will try to articulate my problems with the wifstream, but until then I made an ugly hack.

    If I were to use TCHAR's, then maybe it would generate a binary for processing ASCII files and then another for UNICODE files. Meh.

    ╔╗╔╦══╦╗╔╦══╦╗
    ║╚╝║╔╗║╚╝║╔╗║║
    ║╔╗║╠╣║╔╗║╠╣╠╣
    ╚╝╚╩╝╚╩╝╚╩╝╚╩╝

    codez http://code.google.com/p/zxcvbn/

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,528
    Incidentally, typeid is also a run time operator. For this sort of thing to compile, you need to use template specialisation.

    Code:
    template<class T> class X
    {
         public:
                X() {};
                void set();
    
         private:
              std::basic_string<T> x;
    };
    
    template<class T> void X<T>::set() {}
    
    template<> void X<char>::set()
    {x = "Hello";}
    
    template<> void X<wchar_t>::set()
    {x = L"Hello";}
    
    int main()
    {
          X<char> c;
          c.set();
          X<wchar_t> d;
          d.set();
    }

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,691
    What you have to remember when streaming Unicode (at least with the MSCRT) you have to open the stream in binary mode. Which also means that "\r\n" sequences are not auto-magically converted to "\n" for you. You also have to deal with any BOM that might be at the front of the file - which would tell you if you need to deal with any endianess issues. And since wchar_t is 2 bytes, a wstream is really only good for dealing with UTF-16.

    http://msdn2.microsoft.com/en-us/lib...8e(VS.80).aspx

    For a list of BOM's: http://www.i18nguy.com/unicode/c-unicode.html#BOM

    gg

  9. #9
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    That's pretty clever grumpy, but like, I need to have it be extensible to accommodate an arbitrary string (not just ?hello?)

    ╔╗╔╦══╦╗╔╦══╦╗
    ║╚╝║╔╗║╚╝║╔╗║║
    ║╔╗║╠╣║╔╗║╠╣╠╣
    ╚╝╚╩╝╚╩╝╚╩╝╚╩╝

    codez http://code.google.com/p/zxcvbn/

  10. #10
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,751
    Maybe a struct would be better then? You could always package together the functionality you need and then construct strings of the proper width.

    It would be simpler to work with in that case perhaps, because it could always be a member to some bigger class or whatever you have planned for design.
    Code:
    #include <string>
    
    template < typename charT > 
    struct bar
    {
        std::basic_string< charT > lol, rofl;
    
        bar ( const charT * time, const charT * name  ) :
            lol( time ), rofl( name )
        {
        }
    
    };
    
    int main ( )
    {
        bar< char > a( "Name", "Time" );
        bar< wchar_t > b( L"Name", L"Time" );
    
        a.lol = "example";
        b.lol = L"example";
    }
    But this is just an example; I'm sure there's a tinker to grumpy's solution that works.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,528
    Quote Originally Posted by Tonto View Post
    That's pretty clever grumpy, but like, I need to have it be extensible to accommodate an arbitrary string (not just ?hello?)
    Depends what you mean by "arbitrary string".

    If by "arbitrary string" you mean something that can be fixed at compile time (i.e. in source code) then provide template specialisations of member functions or const/static members to do that. That is essentially an extension of the message I gave above.

    If you mean one that can be set at run time (eg read from a file) then you need to decide on the input format and explicitly convert between representations (i.e. you need to implement the conversion yourself). Since such conversions can mean losing data (a wchar_t is often bigger than a char) a C++ compiler will not provide an implicit conversion of L"string" to/from "sting": pointers to (or arrays of) different types are not implicitly convertable to each other, and using a typecast will not work as you intend.
    Last edited by grumpy; 02-16-2008 at 01:30 AM.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,899
    I think you could get around the problem with a cast. Since the "unused" case would never happen at the runtime, it should be safe.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,528
    Quote Originally Posted by Elysia View Post
    I think you could get around the problem with a cast. Since the "unused" case would never happen at the runtime, it should be safe.
    Would you care to show an example of a cast that will solve this particular problem?

    (For reference: I doubt that a cast will work. But I will be happy to be shown to be incorrect.)
    Last edited by grumpy; 02-16-2008 at 07:50 AM.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,899
    I was thinking something like this:
    Code:
    	basic_string<T> lol, rofl;
    
    	if(typeid(T) == typeid(wchar_t))
    	{
    		lol = (const T*)L"Time", rofl = (const T*)L"Name";
    	}
    
    	if(typeid(T) == typeid(char))
    	{
    		lol = (const T*)"Time", rofl = (const T*)"Name";
    	}
    The cast will basically convert it to the right type so the compiler won't complain.
    It should do the correct cast to type T in both cases, but only the "correct" if will execute, so the unsafe code will never be executed and you should be safe.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,308
    I think you can just forget 'typeid' in this instance, Elysia.
    typeid is also a run time operator
    Template specialisation exists specifically for the purposes of the kind of thing that is being done here.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 08-12-2007, 02:02 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 03:39 PM
  3. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 09:11 AM
  4. question about .net to 6.0 change causing errors
    By jverkoey in forum C++ Programming
    Replies: 17
    Last Post: 03-23-2004, 10:45 AM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21