Conflicting overloads with STL’s wstring and ATL’s CStringW

If you want to overload a function with both STL’s wstring and ATL’s CStringW, you’ll end up with a compiler error:

#include <iostream>  // for cout
#include <string>    // for wstring
#include <atlstr.h>  // for CStringW

using std::cout;

void f(const std::wstring& ws)
    cout << "f(const wstring&)\n";

void f(const CStringW& cs)
    cout << "f(const CStringW&)\n";

int main()

VS2015 emits a message like this:

error C2668: ‘f’: ambiguous call to overloaded function
could be ‘void f(const ATL::CStringW &)’
or ‘void f(const std::wstring &)’
while trying to match the argument list ‘(const wchar_t [7])’

The problem is that the raw L”Connie” string (which is a “const wchar_t[7]”) can be used to initialize both an ATL::CStringW and a std::wstring, since both those string classes have a (non-explicit) constructor overload taking raw C-style NUL-terminated string pointers as input (i.e. “const wchar_t*”).

This ambiguity can be fixed providing another ad hoc overload for the error-generating function:

void f(const wchar_t* psz)
    cout << "f(const wchar_t*)\n";

Or maybe just try to stabilize your code on one string class, or just use functions with different names when you have to deal with both CStringW and wstring.


Leave a Reply

Your email address will not be published. Required fields are marked *