1

I was learning boost's variant and found that it makes implicit conversion from char* to std::string in this snippet:

boost::variant<int, char*, std::string> v; // implicitly converted from char* to std::string, so we can't store char* and std::string both? v = "123"; std::cout << "boost::variant value: " << boost::get<std::string>(v) << std::endl; v = 1; std::cout << "boost::variant value: " << boost::get<int>(v) << std::endl; v = "123"; std::cout << "boost::variant value: " << boost::get<char*>(v) << std::endl; 

So the exception will be raised by the boost::get<char*>(v) call. I wondered a bit and tried to make it more fair: change char* to const char* in the typename list:

boost::variant<int, const char*, std::string> v; v = "123"; std::cout << "boost::variant value: " << boost::get<std::string>(v) << std::endl; 

Now exception is correct. But my question is: why compiler/library chooses std::string instead of char* as I specified? I understand, that v = "123" is assignment of const char* but why it converts to std::string and not char*?

7
  • 2
    Why do people insist on adding the c tag to questions that have nothing to do with C? Commented Feb 25, 2015 at 10:54
  • Well, sorry, I was pointing at "c++" first but it added "c". Next I forgot to remove it. Commented Feb 25, 2015 at 11:00
  • If that is a reproducible problem (if you can describe the exact steps you took to add the c++ tag, and where the c tag got added by the system instead), I encourage you do report it as a bug. It's never happened to me, and I can't manage to even make c and c++ both show up at the same time in the tag selection, but I won't rule out the possibility of you doing something I haven't thought of trying. Commented Feb 25, 2015 at 11:03
  • Thanks for the suggestion. I don't remember already what I did exactly but I remember I was pointing at "c++", but maybe I also I did something else in the moment (click, key press, etc).. Okay, if I will reproduce it I'll do what you suggested to me. I also did not mean to put "c" tag here but now I think about - why not? The question is about c-type conversion between char* and const char*, is not it? Commented Feb 25, 2015 at 11:07
  • No, C and C++ are different languages, and even for the types that exist in both languages, the conversions between those types are different in C++ than they are in C. If C did have an implicit conversion from const char * to char * (it doesn't, luckily), that would have no impact on C++. If C makes "123" a char[4] rather than const char[4] (it does, unfortunately), that too has no impact on C++ and is not relevant to your question. Commented Feb 25, 2015 at 11:09

2 Answers 2

3

const char * doesn't implicitly convert to char * because that would be unsafe. The whole point of const is that you don't inadvertently attempt to modify the object. Suppose that const char * did implicitly convert to char *. Then what's preventing programs such as these:

#include <cstdio> void f(char *s) { *s = 'a'; } int main() { const char *str = "Hello!"; f(str); std::puts(str); } 

which are obviously a massive error, from compiling without even so much as a warning?

Sign up to request clarification or add additional context in comments.

Comments

1

Because there's an explicit conversion from const char * to std::string from std::string and dropping const is never done implicitly for obvious reasons.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.