S_M
S_M

Reputation: 85

Wrong detection in the same name functions

I have two functions with same name and multiple signature as below :

#include <iostream>
#include <string>
using namespace std;

//Function for bool data

void test(const bool &b) {
    wcout << L"bool data is : " << b << endl;
};

//Function for   wstring data

void test(const wstring &w) {
    wcout << L"wstring data is : " << w.c_str() << endl;
};

void main() {
    test(L"my string  data for test");
    test(true);
}

Why when i use the wstring value type void test(const bool &b)function executed?

Upvotes: 1

Views: 91

Answers (4)

TartanLlama
TartanLlama

Reputation: 65770

A wide string literal is of type const wchar_t [N+1]. When you pass it to test, there are two possible paths:

  1. const wchar_t[N+1] -> const wchar_t* -> bool
  2. const wchar_t[N+1] -> const wchar_t* -> std::wstring

The first version is chosen because overload resolution prefers the standard boolean conversion to bool is preferred to the user-defined conversion to std::wstring.

One possible solution would be to explicitly create the std::wstring, as Martin suggests, but I think this is likely to bite you again later on. I would instead either have two functions with different names to avoid the issue, or add an overload which takes a const wchar_t* and forwards on to the std::wstring version.

void test(const wchar_t* w) {
    test(std::wstring{w});   
}

Upvotes: 4

All answers being given, if you use c++14, you could just tweak the literal you pass in the first case.

#include <iostream>
#include <string>
using namespace std;

//Function for bool data

void test(const bool b) {
    wcout << L"bool data is : " << b << endl;
};

//Function for   wstring data

void test(const wstring &w) {
    wcout << L"wstring data is : " << w.c_str() << endl;
};

int main() {
    test(L"my string  data for test"s);
    test(true);
    return 0;
}

output:

wstring data is : my string data for test
bool data is : 1

Upvotes: 3

DeathTails
DeathTails

Reputation: 468

Your string literal is not a wstring but a const wchar_t[] which is more easily converted to a bool (via decay into a const wchar_t*) than a wstring.

Running your code in Visual Studios gave me this error:
warning C4800: 'const wchar_t *' : forcing value to bool 'true' or 'false' (performance warning)
which gives a pretty much perfect explanation.

Upvotes: 3

You have been bitten by the rules for implicit type conversions. The problem is that L"my string data for test" is neither a bool nor a std::wstring. It is in fact a const array of wchar_t.

It can be converted to bool by array decays to pointer, followed by pointer to bool conversion (test if the pointer is null - it isn't).

It can be converted to std::wstring by calling the appropriate constructor.

Your problem is that the standard calls for the the compiler to choose the "wrong" one.

Probably your best bet is to write a suitable additional overload. For example:

void test(const wchar_t* p)
{
   test(std::wstring(p));
}

Upvotes: 1

Related Questions