Closed smiley closed 8 years ago
Hi @smiley,
I already had several requests about MSVC support, but even the 2015 version still lacks full C++11 support (see #50). As one of the goals of this project is to embrace "Modern C++", I do not plan to remove those features that are not supported by MSVC, I'm sorry :-)
I'm happy to link to forks that support MSVC though ;-)
All the best Niels
I understand that and you shouldn't remove features to support another compiler, but some of the uses don't seem to be necessary. If you remove them, or use simplified forms of them, you can support VS2015+ without sacrificing the clarity & cleanliness of the code.
For example, line 137 (the first error) makes a type-aliasing declaration with its own class name:
/*!
@brief an iterator for a basic_json container
@ingroup container
*/
using iterator = basic_json::iterator;
And to a forward-declaration of the same name:
class iterator;
// ...
public:
/// a random access iterator for the basic_json class
class iterator : public std::iterator<std::random_access_iterator_tag, basic_json>
Is there a difference between these two? Because the second one works perfectly in VS: (and pretty much solves the one remaining problem in #50)
template<class T>
class foo {
class bar;
// Option 1:
using foobar = foo::bar;
// Option 2:
using foobar = bar;
public:
class bar : public std::bar<A, foo>
noexcept
is supported from VS2015, so I'll leave it there.
In line 386 you use and
instead of &&
. I see that it's a legitimate extension of C++ that isn't implemented in VC++, can you include the relevant header (iso646.h) on Windows? It's already available in Visual Studio's headers.
And that's just a bunch of changes that significantly improve matters. By doing the above I managed to reduce the number of errors on VS2013 to 33 (from 100+) and the only remaining quirks are language matters (referencing my own template class without a template argument specifier), user-defined string literals and referencing template classes in the type specifier without their type specifiers. (I had to remove noexcept
as I had VS2013 locally installed, but I considered it supported)
Of them, the following are implemented in VS2015:
noexcept
The last two might be implemented, I just can't find them at all (not even in "unimplemented" state) on the C++11/14/17 page at MSDN.
(Sorry if I'm wrong about some of this, I'm still learning my through parts of C++11 and, apparently, C++14/17)
I addressed the issue with the (admittedly superfluous) type alias and also included <ciso646>
for the operators. If there are other issues that can be fixed so easily, please let me know.
I added a CMake file and enabled AppVeyor again. Though I chose MSVC 2015, the build is still failing (see https://ci.appveyor.com/project/nlohmann/json/build/370). As I am neither an expert in MSVC nor CMake, I am clueless how to proceed. Maybe you have an idea. (This also affects issue #50).
It looks like it still uses Visual Studio 2013 (VS12 is 2013, VS13 is 2015).
How is the project (.vcxproj) configured? A project can still be run with a newer version of Visual Studio but compiled with an older one.
It is all configured through the appveyor.yml and CMakelists.txt files. Do you have an idea what needs to be changed?
I made a change and tried again: https://ci.appveyor.com/project/nlohmann/json/build/372. It now seems to use Microsoft Visual Studio 14.0. However, there are still 100s of errors. :-(
Appveyor now runs with 19.0.22609.0 (Visual Studio 2015 CTP 6). There are still 100s of errors, but maybe some of them can be fixed easily. Help would be greatly appreciated!
I'll look into it tonight, maybe I could resolve more of these.
In case it's helpful: Microsoft has released VS 2015RC with a table of the C++ features supported. I don't have that much experience with heavy template use, so I haven't given a try yet. I will probably do, but is unlikely I can help much. :)
This sounds interesting. It seems, however, that AppVeyor has not updated to that version yet.
AppVeyor now has "Visual Studio 2015 RC" (MSVC 19.0.22816.0) as option. The errors seem to be the same: https://ci.appveyor.com/project/nlohmann/json/build/397. Can anyone support this?
Yes, I tried with Visual Studio 2015 RC locally and the errors seem the same. Just in case, a quick copy and paste:
Thanks for trying. So I can take home that even Visual Studio 2015 is unable to compile the code.
I managed to take this down to one error by removing all basic_json::
references. Looks like this in-class, same-class referencing was tripping up MSVC, and without it the compiler still knows to use the in-class match when searching for the symbol.
Now all I'm left with is this:
/// create a string (implicit)
template <class V, typename
std::enable_if<
std::is_constructible<string_t, V>::value, int>::type
= 0>
inline basic_json(const V& value)
: basic_json(string_t(value))
{}
1>d:\github\json\src\json.hpp(407): error C2794: 'basic_json': is not a member of any direct or indirect base class of 'nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,double,std::allocator>'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(761): note: see reference to class template instantiation 'nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,double,std::allocator>' being compiled
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(790): note: see reference to class template instantiation 'std::is_nothrow_constructible<_Ty,nlohmann::basic_json<std::map,std::vector,std::string,bool,int64_t,double,std::allocator> &&>' being compiled
1> with
1> [
1> _Ty=nlohmann::json
1> ]
1> d:\github\json\src\json.hpp(4869): note: see reference to class template instantiation 'std::is_nothrow_move_constructible<nlohmann::json>' being compiled
@smiley, that sounds interesting! How did you remove the references? Did you replace basic_json
with the lengthy template list or did you use a typedef or ´using`?
I really did just remove basic_json::
from every using
statement, and made sure Visual Studio actually picked the right class by hovering over it & seeing the resulting class. (It also compiled fine and had nothing with that same name in the global namespace)
I still kept the redundant statements, though, as a sort-of documentation if anyone wonders what iterator
(for example) means in each class' context.
How cool! :+1:
The remaining error seems to be an issue with the delegating constructor, right?
It seemed like it, but if I replace the constructor call with the body of the called constructor, it still throws the same error so it looks like typename std::enable_if<std::is_constructible<string_t, V>::value, int>::type = 0
is the culprit. :-/
ssize_t
also didn't match anything, but looks like it's easily fixable with an #include
and typedef
.
Also, I have no idea why but AppVeyor still has a lot of trouble with this (102+ errors), even on VS2015 RC: https://ci.appveyor.com/project/smiley/json
The version number matches, but locally this compiles fine on my end. (And all I did was make an empty solution, add the .hpp
file. #include
it and copy-paste the first example.) It even compiles successfully if I remove that pesky constructor.
This is odd. If I remove the enable_if
condition or force it, errors happen and lines like this fail to work:
j["answer"]["everything"] = 42;
But if I remove the constructor altogether, that line -- and actual string uses -- work perfectly. @nlohmann, is there a need for this implicit constructor?
(And while we're discussing strings, what about Unicode support?)
Also, AppVeyor isn't wrong in the end -- std::vector
support in this and STL container operations don't compile.
You're right - without the constructor, all tests run without problems. I'll see if I can find out why I added it in the first place.
What you mean with Unicode support? There are plenty of test cases parsing all kinds of Unicode characters.
And I don't know what you mean with AppVeyor and std::vector
.
Earlier I said that I have no idea why AppVeyor still fails at compiling this, but then I noticed the std::vector
-based examples (e.g.: make json array from std::vector
) don't compile for me as well, so the interoperability with STL containers doesn't work for some reason.
I haven't looked at test cases, but if I pass on wchar_t
, char16_t
or char32_t
it treats them as boolean values for some reason, not as valid strings.
This is a great library. I got it compiling with MSVC2013 with some reasonable changes and a few hacks. Basic functionality appears to be working. I have not run the unit tests.
Here is the full set of patches that I applied: https://github.com/nlohmann/json/compare/master...RossBencina:msvc2013-patch
The patches fall into the following categories:
Maybe some of these can be fixed in master by using different constructions? The adding typename ones might be harmless?
I have #ifdefed using _MSC_VER defined (no version number check). For a production patch this should be based on some other feature detection.
At this stage I do not intend to maintain the patch set. But if you need any more info about compiler errors, or would like me to try something then feel free to @-mention me and I'll try to take a look.
Hi @RossBencina, thanks for the deep analysis. I shall have a closer look. The typename
stuff shall definitely be applied in master. Do you know how the situation in MSVC 2015 looks like?
@nlohmann No problem. I'm not eactly sure about MSVC 2015. RC1 was released last month. There is a supported language features table here: http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17-features-in-vs-2015-rc.aspx
Of relevance to json library, the following are added in MSVC2015 (according to the above link):
According to the following link std::snprintf is now supported: http://stackoverflow.com/questions/27754492/vs-2015-compiling-cocos2d-x-3-3-error-fatal-error-c1189-error-macro-definiti
So it may be that your library works without problems on MSVC2015. Or maybe some of those compiler-bug like issues are still there (03b0d1d, 94de11e). Hopefully someone else can try and let us know :)
@nlohmann I just looked at the Appveyor link you posted above. I think those typename
fixes I suggested will help.
El Sunday 24 May 2015, Ross Bencina escribió:
@nlohmann I just looked at the Appveyor link you posted above. I think those
typename
fixes I suggested will help.
This is great to read. In the testing I mentioned in the previous messages, I did get less errors sprinkling typename's here and there, but since templates are not my thing, I could not really now if I was doing it right.
I'll have a look at your commits and try to see if I can get it built with the tests passing under MSVC2015.
Alex (a.k.a. suy) | GPG ID 0x0B8B0BC2 http://barnacity.net/ | http://disperso.net
Regarding 03b0d1d There are two constructors with the same signature:
/// create an array (implicit)
template <class V, typename
...
inline basic_json(const V& value)
...
/// create a string (implicit)
template <class V, typename
...
inline basic_json(const V& value)
If for instance, you change second constructor to inline basic_json(const V value)
, it compiles.
That's good to hear! I'll have a look to clean this up in the master branch.
Furthermore, snprintf
is not used any more, so that is another thing that won't be a problem any more.
Oh.. this template magic really puzzles me. I've just moved up string (implicit)
constructor, so it's the first templated constructor and it also works (without changing signature).
Even though some basic functionality works, I still can't compile unit tests.
Can you try leaving the order as is and add the line not std::is_constructible<string_t, V>::value and
to the implicit array constructor to remove the ambiguity?
No it's not working.
That's too bad. By the way, I added some of the fixes listed above in the last commit.
(Still errors... With MSVC 2015: https://ci.appveyor.com/project/nlohmann/json/build/430)
I've made some progress: f2ae9e989 but commented some unit tests to make the process iterative.
The hardest part left is iterators. I think I'll just have to rewrite it a little bit. MSVC behaves differently in choosing overload between:
iterator end() noexcept
and
const_iterator end() const noexcept
Inside a templated method MSVC will always choose the first variant. I've checked how std::vector iterators are written and it turns out that you can assign iterator
to const_iterator
.
nlohmann, what do you think about my PR https://github.com/nlohmann/json/pull/88 ?
Hi @kepkin, thanks for the PR. I didn't find the time to look at it, yet. I hope to come to this on Wednesday.
I would suggest that using MSVC 2015 as a target is optimistic. very few developers are using it yet, or intend to use it next year, or in the near future (the next 3 years). i do not agree with this approach, but its the practical reality we have to deal with.
i will have to get this to work with vs2013 if i want to use it for instance... and possibly 2012 and 2010 too... maybe even gcc 4.2 and some clang as well.
i can probably share this back when done if its relevant... (and of course, if i actually do it ;))
I don't think it's that optimistic. Visual Studio 2013 & 2015 are the only two editions with free, full (no language restrictions) versions. If someone is going to begin developing for Windows, it'll probably be using VS2015, and recent Windows projects are already starting off with VS2013+ Community. (see OpenRCT2)
Plus, if you're going to use a relatively recent version of GCC to support this on other platforms, I think it's fine to ask for VS2015 on Windows. (This is C++11/14, after all)
Hi @semiessessi, I would be glad to see solutions that support more compilers. At the same time, I would try to avoid preprocessor-heavy code which tries to circumvent all the shortcomings of too old compilers at all costs. In the end, C++11 is the main requirement, and I do not see how GCC 4.2 can support this (https://gcc.gnu.org/projects/cxx0x.html).
yeah, gcc 4.2 might be especially difficult since it would require working around the lack of C++ 11 in a way that works across everything. it is possible, but it leaves you with less friendly code in the long run...
i may have to settle for a crusty old C library instead, if only because of this constraint. :(
On 13 July 2015 at 23:11, Niels notifications@github.com wrote:
Hi @semiessessi https://github.com/semiessessi, I would be glad to see solutions that support more compilers. At the same time, I would try to avoid preprocessor-heavy code which tries to circumvent all the shortcomings of too old compilers at all costs. In the end, C++11 is the main requirement, and I do not see how GCC 4.2 can support this ( https://gcc.gnu.org/projects/cxx0x.html).
— Reply to this email directly or view it on GitHub https://github.com/nlohmann/json/issues/62#issuecomment-121077097.
I was about to use this for a C++ project in Visual Studio 2013, but the header fails compilation entirely, thanks to a myriad of errors:
This is on VS2013, and as far as I know it supports 90% of the standard (but not some of what you're using here, like
noexcept
).Are you planning to support Visual Studio/Windows some time later on?