Why does the compiler choose bool over string for implicit typecast of L?
First, the cause of this issue: C++ Standard [over.ics.rank]/2.1
1 defines an order for conversion sequences. It says that a user defined conversion sequence is worse than a standard conversion sequence. What happens in your case is that the string literal undergoes a boolean-conversion (defined at 4.12
. This is a standard conversion). It does not use the user defined conversion to std::wstring
which would be needed if it took the other overload.
I would recommend to simply change the name of one of the overloads or adding an overload that accepts the string literal directly (using parameter type wchar_t const*
).
1)
When comparing the basic forms of implicit conversion sequences (as defined in
[over.best.ics]
)(2.1) a standard conversion sequence is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and
(2.2) a user-defined conversion sequence is a better conversion sequence than an ellipsis conversion sequence.
Why is there an implicit type conversion from pointers to bool in C++?
It's very common in C to write this
void f(T* ptr) {
if (ptr) {
// ptr is not NULL
}
}
You should make a const char*
constructor.
C++: avoid automatic conversion of string to bool in overloads
You could add an template overload that takes a reference to array of char
of size N
where N
is a template parameter, and/or one that accepts a const char*
.
template <std::size_t N>
static void printValue(sts::ostringstream& out, const char (&str)[N])
{
out << str;
}
How to prevent implicit conversion from char array to bool
You can declare a function that takes const char*
and don't provide a definition:
void setBar(const char*);
This will make it fail at link time. You're still left will all other implicit conversion, though - from any pointer to bool, integral to bool, floats to bool...
Another option:
struct Foo {
void setBar(bool bar_) {}
private:
template<typename T>
void setBar(T bar) {}
};
This way you'll get an error about it being private if you call it with anything else than bool
.
Implicitly casting to bool?
You need to be explicit about the argument to the constructor:
JsonValue stringItem(std::string("test"));
What is happening is that you are getting an implicit conversion from const char*
to bool
, because this is a conversion between built-in types, and a better match than the conversion from const char*
to std::string
, which is a conversion involving a built-in type.
Alternatively, you can add a constructor that takes const char*
and stores a string internally. This is a better option because it avoids the easy to make error you encountered:
JsonValue::JsonValue(const char* astr)
: mType(Type::String) {
mData.str = new std::string(astr);
}
Note that on the surface these seems to be no reason to store a dynamically allocated string. This probably adds unnecessary complications.
How does the compiler makes this conversion implicitly?
It's implicitly converting from unique_ptr
to bool, and then from bool to int to do the multiplication.
(bool to int means true is 1 and false is 0)
What is the performance implication of converting to bool in C++?
I was puzzled by this behaviour, until I found this link:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99633
Apparently, coming from the Microsoft Developer who "owns" this warning:
This warning is surprisingly
helpful, and found a bug in my code
just yesterday. I think Martin is
taking "performance warning" out of
context.It's not about the generated code,
it's about whether or not the
programmer has signalled an intent to
change a value from int to bool.
There is a penalty for that, and the
user has the choice to use "int"
instead of "bool" consistently (or
more likely vice versa) to avoid the
"boolifying" codegen. [...]It is an old warning, and may have
outlived its purpose, but it's
behaving as designed here.
So it seems to me the warning is more about style and avoiding some mistakes than anything else.
Hope this will answer your question...
:-p
Strange constructor behavior
"false"
is a const char[6]
which decays to const char*
and pointers are implicitly convertible to bool
. That's why the compiler can call your constructor taking a int
and a bool
, since the compiler is allowed to perform one implicit conversion to make a function argument match.
Related Topics
Find Two Elements in an Array That Sum to K
Addition of Two Pointers in C or C++ Not Supported. Why
Borderless Window with Drop Shadow
Function Already Defined Error in C++
How to Find the Current Directory
What Is Aggregate Initialization
How to Use Unicode Range in C++ Regex
Undefined Reference to Mempcy@Glibc_2.14 When Compiling on Linux
Qsqldatabase: Qmysql Driver Not Loaded on Ubuntu 15.04 64Bits
Why Do Two Functions Have the Same Address
Calculate System Time Using Rdtsc
Overloading Operator<< for a Templated Class
Does New Line Character Also Flush the Buffer
Name Hiding and Fragile Base Problem
Difference Between Regex_Match and Regex_Search
Writing a Matrix into a Single Txt File with Mpi
How to Allocate a Specific Memory Address Using Pointers in C++