Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Casting to std::string not working in VS2015 #861

Closed
jojastahl opened this issue Dec 7, 2017 · 9 comments
Closed

Casting to std::string not working in VS2015 #861

jojastahl opened this issue Dec 7, 2017 · 9 comments
Labels
platform: visual studio related to MSVC state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated

Comments

@jojastahl
Copy link

jojastahl commented Dec 7, 2017

The following doesn't compile in Visual Studio 2015 Update 3:

      json o = { { "name", "value" } };
      std::string s1;
      s1 = static_cast<std::string>(o["name"]);  // Failing line

It gives the following error:

error C2440: 'static_cast': cannot convert from 'nlohmann::basic_jsonstd::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::adl_serializer' to 'std::string'
note: No constructor could take the source type, or constructor overload resolution was ambiguous

I tried this with the develop branch aswell as the 2.1.1 release.
I'm using Visual Studio 2015 Update 3 with compiler version 19.00.24215.1 for x86

This is related to #188 and #167. I have to exclude the _MSC_VER check, so that the condition included in the VS build, too. However, this condition has been introduced to fix #167 as far as I understand. Was #167 a problem in VS2015 pre Update 3 only, or hasn't a test been added for #167? I can compile and run all unit-xxx tests with the check removed.

@theodelrieu
Copy link
Contributor

Could you try the following?

s1 = o["name"].get<std::string>();

@jojastahl
Copy link
Author

That works. However, I think the other way should be made to work, too.

@theodelrieu
Copy link
Contributor

Is the error message showing something about operator=?

If so, this is a known issue, unfortunately this a C++ problem, see this doc section for more details

@jojastahl
Copy link
Author

The error message is in my original post. operator= is not mentioned.
You could even remove the s1 = and it will fail to compile.

      json o = { { "name", "value" } };
      static_cast<std::string>(o["name"]);  // Failing line

@theodelrieu
Copy link
Contributor

Here is the output on GCC, which is more helpful:

t.cpp: In function ‘int main(int, const char**)’:
t.cpp:7:29: error: call of overloaded ‘basic_string(nlohmann::json&)’ is ambiguous
static_caststd::string(j);
^
In file included from /usr/include/c++/7/string:52:0,
from /usr/include/c++/7/stdexcept:39,
from /usr/include/c++/7/array:39,
from src/json.hpp:33,
from t.cpp:1:
/usr/include/c++/7/bits/basic_string.h:531:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]
basic_string(basic_string&& __str) noexcept
^~~~~~~~~~~~
/usr/include/c++/7/bits/basic_string.h:437:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]
basic_string(const basic_string& __str)
^~~~~~~~~~~~
/usr/include/c++/7/bits/basic_string.h:429:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]
basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT
^~~~~~~~~~~~

It's the same issue basically, since the json object has a conversion operator for every type, the compiler does not know which one it should call. operator std::string const&()? operator std::string&&()? etc...

One workaround is to use static_cast<std::string const&>(o["name"]) (or std::string&&).

I don't think we can do anything more about it unfortunately.

@nlohmann nlohmann added the platform: visual studio related to MSVC label Dec 7, 2017
@jojastahl
Copy link
Author

So why this compiles in VS, if the condition

and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value

is included for basic_json::operator ValueType() const?

When you compiled with GCC, did you explicitly exclude this condition (as it is only excluded if _MSC_VER is defined, which shouldn't be the case for GCC)? If no, VS and GCC are behaving diffrently here.

Nevertheless I do not understand the behavior. I thought that the compiler would use the operator ValueType() const if I do static_cast<Type>(json), provided that it is not explicitly disabled by SFINAE. But it seems it is ignoring it and choosing the Type constructor instead.

@theodelrieu
Copy link
Contributor

I haven't touched the library code when I compiled your code.

As to why the constructor is called, cppreference will be more clear and accurate than me.

@nlohmann
Copy link
Owner

Any idea how to move forward here?

RealGreenDragon added a commit to RealGreenDragon/yocto-gl that referenced this issue Jan 18, 2018
On MSVC 2017 the implicit cast to string doesn't work due a C++ issue, so I fix it following the JSON library usage.
Reference:
https://github.com/nlohmann/json#basic-usage
nlohmann/json#861
@stale
Copy link

stale bot commented Jan 22, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Jan 22, 2018
@stale stale bot closed this as completed Jan 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: visual studio related to MSVC state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated
Projects
None yet
Development

No branches or pull requests

3 participants