2

Background

I'm working on C++11 JSON mapping classes to introduce syntactically intuitive and safe objects which can serialize/deserialize itself into JSON representation.

The Question

I need to provide a good proxy for arithmetic types (mainly for int, unsigned, float, double). How to implement such thing? The first idea is to implement template class overloading all arithmetic, bitwise and comparison operators. But what overload should I write in order to avoid unnecessary work? What about cast operators? What should be return type of operator+?

Simple incomplete implementation showing the idea:

template <typename T>
class Proxy {
    T mValue;
public:
    Proxy(T value = T()) : mValue(value){}

    //Should it be defined like this...
    Proxy &operator+=(T value) {
        mValue += value;
        return *this;
    }

     //Or maybe like this...
    template <typename U>
    Proxy &operator+=(U &&value) {
        mValue += std::forward<U>(value);
        return *this;
    }

    //Should this return T or Proxy<T>?
    T operator+(T value) {
        return mValue + value;
    }


    //Is it necessary?
    operator T() const {
        return mValue;
    }

    //...
};

Alternative

But should I implement the primitive JSON fields as a proxy classes? Maybe there's a better way. For instance, I also consider making the internal value public, so instead of writing:

json.intField += 4;

the user would have to write

json.intField.value += 4;

This syntax is not as intiutive and clear as I would like it to be, but that's also an option.

For everyone telling me how to implement JSON in C++ - that's not my question! Proxy pattern has wider usage!

Rames
  • 918
  • 11
  • 27
  • `JsonValue` is mostly a `std::variant, std::map>`. Your Question is how to implement `class Number` (instead of simply using `double`) ? – Jarod42 Aug 22 '16 at 07:48
  • @Jarod42 Forget about JSON, my question is about how to implemement good proxy class which works for C++ arithmetic types. Do you know what a proxy pattern is? And apart from that my JSON implementation is not a `std::map` with strings as keys, because that's error prone! – Rames Aug 22 '16 at 08:05
  • "objects which can serialize/deserialize **itself** into JSON representation." Why? Maybe I got your idea wrong, but if I need to write my class hierarchy in terms of your proxies to have it working, it'd be quite a heavy burden (especially if I need to get back to extensively adjust my legacy code). The usual practice is to design external non-intrusive "serializers" specialized for the "archiving" format. – Adrian Colomitchi Nov 03 '16 at 21:47
  • @AdrianColomitchi Yes I understand your concern and I'm familliar with the idea of how it's done in `boost::serialize`. Still my JSON mapping idea aims to allow writing and using JSON classes almost as easly as JSONs in javascript therefore it introduces some limitations in other areas. – Rames Nov 03 '16 at 21:56
  • Mmmm... so it seems I cannot change your mind, eh? See [Access to private members](http://bloglitb.blogspot.com.au/2011/12/access-to-private-members-safer.html) or [access private member using template trick](http://stackoverflow.com/questions/12993219/access-private-member-using-template-trick) or [stealer](https://github.com/zjx20/stealer) (the technique in this last one may allow you to create proxies with access to methods). Let me know if it helps you. – Adrian Colomitchi Nov 03 '16 at 22:16
  • @AdrianColomitchi There's plenty of other C++ JSON libraries which allow you to use the pattern you are talking about. My idea is different, I will post it on codereview when I consider it good enough, then we can talk about it. For now I just need a good proxy... – Rames Nov 04 '16 at 08:58
  • It's unclear what this question is asking for. What do you specifically need `Proxy` for, that you can't accomplish with just `T`? – Barry Nov 04 '16 at 16:29
  • Have you had a look at this library https://github.com/nlohmann/json ? It seems to have some of the characteristics you are trying to achieve, maybe you can see how they have done it – harmic Nov 07 '16 at 10:02
  • @harmic I actually use it, but it doesn't map object's fields so it doesn't provide any sort of compile time safety. You have to write `json["field"]` instead of `json.field`. Anyway this question is about proxy pattern, not json... – Rames Nov 07 '16 at 13:08
  • how about `double`? (as the common type) – lorro Nov 09 '16 at 22:27
  • @lorro Of course, the implementation of `double` proxy would be helpful :) Stop talking about JSON please, that's not the point of the question.... – Rames Nov 10 '16 at 10:28
  • @Rames: have `double` as the common type and implement `std::ostream& operator<<(std::ostream&, double)` and `std::istream& operator>>(std::istream&, double&)`. Fortunately c++ is not a language where everything is bound to reside in the class :). If you really need a proxy (e.g. to pass around) then let it store a single public `T&` (which will automagically become `const T&` when `T` is `const`) and create it on-the-fly, where it's needed (visitor pattern). What else would you need the proxy for? – lorro Nov 11 '16 at 18:49
  • @lorro There is already a implementation of these operators so there's no reason to implement it (http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/ ). Have you ever been using, for instance Java and gson library? I try to get as close to it with C++ as possible. – Rames Nov 12 '16 at 11:09
  • @Rames: My bad, I meant 'implement via'. I.e., when you're serializing a double, serialize it to an ostream-like something. (like stringstream). Don't try to mimic Java - in c++, many things are different, and that's right. If you do, you'll have the XY-problem where you limit your thinking of a specific (kind of) solution instead of solving the problem itself. – lorro Nov 12 '16 at 17:13
  • @lorro I think I understand your point of view - the class shouldn't be responsible for serializing itself. Still, really, most of commenters don't understand my idea and that's probably my mistake, but really I'm far more interested in answer to the question, than in design advices where you do no really know my idea and motivation. There are many JSON libraries I'm writting MAPPING library (heard about ORM?). – Rames Nov 12 '16 at 21:33
  • @Rames: 'where you do no really know my idea and motivation' - share it with us and we might be able to give a better advice. Also note that, in c++, free functions in the same namespace as your type/class that take the type/class are part of the type/class interface, so - from this point of view - it's the same if it's inside the class or outside but in the interface. – lorro Nov 13 '16 at 11:35

0 Answers0