2

I am in the process of porting some code from Visual studio to mingw gcc. I came across this statement

if ( mnode.GetTag() == _T( "val" ) )    
        return  true;

this is the definition of GetTag() method

const std::wstring &GetTag() const;

I am getting the error

error: no matching function for call to 'std::basic_string<wchar_t>::basic_string(const char [6])'|

Now after reading this I am still not sure how to resolve this issue. Any suggestions on why this error is being shown up ? is it because of wstring ?

Community
  • 1
  • 1
James Franco
  • 4,516
  • 10
  • 38
  • 80
  • What's the `_T()` macro defined as when you build using MinGW? – Praetorian Feb 20 '15 at 22:12
  • @Praetorian, In my experience, MinGW emulates most of the MSVC stuff for Winapi usage. – chris Feb 20 '15 at 22:12
  • same as in visual studio. It uses #define _T(x) __T(x) – James Franco Feb 20 '15 at 22:13
  • Thats why I am confused why I am getting that error – James Franco Feb 20 '15 at 22:13
  • @chris Hmm, then that error doesn't make sense. `mnode.GetTag() == L"val" ` should compile – Praetorian Feb 20 '15 at 22:13
  • @Praetorian, The length is wrong, but presumably `UNICODE` isn't defined. – chris Feb 20 '15 at 22:14
  • 1
    Sounds like you don't have _UNICODE defined. See: https://msdn.microsoft.com/en-us/library/dybsewaf.aspx – MrEricSir Feb 20 '15 at 22:15
  • 2
    @JamesFranco, The T variants use narrow strings or wide strings depending on defined preprocessor values. They're way outdated. Use narrow strings or wide strings explicitly. When interfacing with the Windows API, prefer to use the wide versions. – chris Feb 20 '15 at 22:16
  • 1
    @JamesFranco `__T()` is just another macro, if you trace it all the way down you'll see it expands into `L` or nothing depending on whether the `UNICODE` (or maybe `_UNICODE`) preprocessor symbol is defined or not. Sounds like you don't have it defined, in which case it also looks like you copy-pasted the wrong error statement. The one corresponding to the line of code you've shown should say `const char[4]` instead of `const char[6]` – Praetorian Feb 20 '15 at 22:17
  • @Praetorian that did the trick. Could you explain whats the difference between __T and L ? Enabling unicode did the trick could you put that down as the answer – James Franco Feb 20 '15 at 22:23
  • 1
    Adding to the malaise. There are actually *two* sets of macros and qualifiers. `UNICODE` and `_UNICODE`, and `TEXT()` and `_T()`. One set is provided via (and for) the Windows API, the other via the MSVC runtime. Yeah, what fun. – WhozCraig Feb 20 '15 at 22:24

1 Answers1

5

It looks like your problem is that the _UNICODE preprocessor macro is not defined. MSDN explains how this affects string literal enclosed in the _T() macro.

 pWnd->SetWindowText( _T("Hello") );

With _UNICODE defined, _T translates the literal string to the L-prefixed form; otherwise, _T translates the string without the L prefix.

Adding an L prefix to a string literal indicates it is a wide string literal, and std::wstring (or std::basic_string<wchar_t>) defines an operator== overload that takes a wchar_t const * argument, thus allowing your code to compile.

Be aware that there's also a UNICODE macro that's relevant if you're going to be calling functions in the Windows API. Raymond Chen explains the madness quite well in this post.

So, one way to fix your problem is to add both _UNICODE and UNICODE preprocessor symbols to the gcc command line.

But don't do this! This is my opinion on the matter — instead of depending on obscure macros just prefix the string literal with L manually. Especially in this case, since you say that GetTag() always returns a wstring const&, I'd say using the _T() macro for that string literal is a bug.

Even otherwise, when calling Windows API functions, just call the wide character version explicitly. For instance, replace calls to GetWindowText with GetWindowTextW.

Praetorian
  • 106,671
  • 19
  • 240
  • 328