1

我正在创建一个包装JsonCpp的库,允许用户编写模板特化来定义从to和 from to 的转换。它有效,但专业化语法非常不优雅,我想通过避免重复来改进它。Json::ValueTTJson::Value

以下是当前定义转换的方法:

namespace ssvuj // my library's namespace
{
    namespace Internal
    {
        template<> struct FromJson<sf::Color>
        {
            inline static sf::Color conv(const Obj& mObj)
            {
                return sf::Color(as<float>(mObj, 0), as<float>(mObj, 1), as<float>(mObj, 2), as<float>(mObj, 3));
            }
        };

        template<> struct ToJson<sf::Color>
        {
            inline static Obj conv(const sf::Color& mValue)
            {
                Obj result;
                set(result, 0, mValue.r);
                set(result, 1, mValue.g);
                set(result, 2, mValue.b);
                set(result, 3, mValue.a);
                return result;
            }
        };
    }
}

// example usage
ssvuj::Obj objColor; // this Json object contains sf::Color data
ssvuj::Obj objEmpty; // this Json object is empty

sf::Color colorFromObj{ssvuj::as<sf::Color>(objColor)}; // color is initialized by "deserializing" the Json object
ssvuj::set(objEmpty, colorFromObj); // the color is "serialized" into the empty Json object 

我注意到的问题:

  • 类型的重复,sf::Color在这种情况下
  • 使用带有 a 的结构特化的必要性static void(我尝试了特化函数,但它不适用于部分特化,例如T = std::vector<T>

我能想到的让这个更简洁和更优雅的唯一方法是宏,但可能有一些我可以在不使用预处理器的情况下做的事情。想法?

4

2 回答 2

3

对于ToJson方向,您根本不需要模板 - 在输入类型上重载自由函数就足够了:

inline static Obj conv(const sf::Color& mValue)
{
    Obj result;
    set(result, 0, mValue.r);
    set(result, 1, mValue.g);
    set(result, 2, mValue.b);
    set(result, 3, mValue.a);
    return result;
}
于 2013-08-08T15:35:24.407 回答
0

我的解决方案正在实施template<typename T> class Converter;,用户可以专门化。

例子:

template<> struct Converter<sf::Color>
{
    using T = sf::Color;
    inline static void fromObj(T& mValue, const Obj& mObj)
    {
        mValue.r = as<float>(mObj, 0);
        mValue.g = as<float>(mObj, 1);
        mValue.b = as<float>(mObj, 2);
        mValue.a = as<float>(mObj, 3);
    }
    inline static void toObj(Obj& mObj, const T& mValue)
    {
        set(mObj, 0, mValue.r);
        set(mObj, 1, mValue.g);
        set(mObj, 2, mValue.b);
        set(mObj, 3, mValue.a);
    }
};
于 2013-08-09T15:44:39.213 回答