-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
can to_json() be defined inside a class? #1324
Comments
ADL will look in the namespace of the class, but nested classes don't count as "namespaces". If you change "static" to "friend", that would allow you to define it "inside" the class but it's actually being declared in the surrounding namespace. This is kind of cheating to get what you want, and "friend" isn't really meant to be used for this purpose, but it would work. Note that the function is still in the namespace, not a member of Outer or Inner. |
I do think there's an interesting question for @nlohmann here though .. should a member function named "to_json" be allowed by the library? As a corrolary, range-based for loops will look for either a "begin/end" member function (like std::vector::begin) but will also look for an ADL-style "begin/end" function. @cwreynolds : is that sort of what you were asking, or am I twisting your request a bit? |
@jaredgrubb A member function would be nice, but I'd like to hear @theodelrieu 's opinion about this. He implemented all the ADL magic... |
Thanks for looking at this. @jaredgrubb : mostly I wanted to make sure that the thing I tried to do does not work in the current implementation. Working around it, whatever that requires, is OK for me. I will note that I use virtual polymorphic methods to do the actual work, my to_json functions are all like this:
This allows me to define serializeToJson() methods on, say, MyDerivedClass and MyBaseClass, so I can have the MyBaseClass::serializeToJson() handle the data that is defined in the base class and MyDerivedClass::serializeToJson() explicitly call the base class method, plus handle the additional data for the derived class. |
@cwreynolds You're still able to use polymorphism in non-member |
@rmstyrczula (Perhaps worth noting, my original issue was about something else: a class and its |
Sorry for being late on this one. @cwreynolds To answer the original issue, if the inner class is public, you can simply define: class Outer {
public: class Inner{};
};
void to_json(json&, Outer::Inner const&) {} If it is private, About supporting member functions by default, I'm quite opposed to it, mainly for the library code's maintainability. Also, what should the library do if both free function and member function are present? Handling priorities with SFINAE is quite hard (you can look at how we handle However, it is possible to write your own JSON serializer, which would call a member-function |
Thanks @theodelrieu for clarifying. I have nothing to add. @cwreynolds Do you need further assistance? |
No. As I mentioned in my original comment, I had already “worked around” the issue before I brought it up here. Thanks to everyone who provided thoughtful comments. I still think “...it would feel more natural if |
@cwreynolds The problem is that the current approach already uses more magic than I can possibly understand ;-) |
I have to_json() functions defined for classes in the global namespace, and for classes inside my own namespaces. Today I tried to make one for a class defined inside another class. Should that be possible? I'm pretty fuzzy on the details of how ADL works. I tried defining to_json() as a static method in the scope of the outer class, with a second argument of the inner class. I kept getting ‘Static_assert failed "could not find to_json() method in T's namespace" ’ until I moved the inner class (and its to_json()) out into the global namespace. I can live with that, but the inner class is used only within the outer class and seemed like it should be defined there.
The text was updated successfully, but these errors were encountered: