Consider the following code:
#include <cstdio>
#include <initializer_list>
using namespace std;
class A {
public:
A(const char*, void*) { printf("const char*, void*\n"); }; // #1
A(initializer_list<char*>) { printf("initializer_list<char*>\n"); }; // #2
};
void F(const A&) {};
int main(int, char**) {
F({ "A", new char[256]() });
};
I have a function F
that I can call with any argument that is_constructible
to class A
.
If I run the program, I see that constructor #2 is called, and I get a warning like: ISO C++11 does not allow conversion from string literal to 'char *const'
for the first argument. C++ is automatically casting this parameter from a string literal to a char*
in order for the call to match the signature initializer_list<char*>
.
But the compiler could also try to cast the second parameter into a void*
so that the call matches the signature const char*, void*
instead.
Both invocations take 'the same number of steps' to go from invocation to 'matching signature' but for some reason the compiler chooses the latter.
I'd like to understand what is the rationale behind this choice, and also, if there's any chance to 'hint' the compiler to use constructor #1 whenever the first argument is a string literal.
On the big picture,
I want calls like: F({ "A", new char[256]() })
to choose constructor #1,
but calls like F({ (char*)"A", new char[256]() })
to choose constructor #2.
Compiler details: Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) Target: x86_64-apple-darwin14.1.0 Thread model: posix