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() { f(L"Connie"); }
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.