1

Я создаю a library, который оборачивает JsonCpp позволяет пользователю писать шаблон специализаций для определения переходов из Json::Value в T и от T до Json::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 в этом случае
  • Необходимость использования структуры специализации с static void (я пробовал специализированные функции, но он не работает для частичных специализаций, таких как T = std::vector<T>)

Единственный способ, которым я могу думать о том, чтобы сделать этот менее подробный и элегантный, - это макрос, но, вероятно, я могу обойтись без использования препроцессора. Идеи?

+1

Почему вы хотите, чтобы два типа для преобразования, а не одного типа, который предлагает функцию '' fromJson' и toJson'? В качестве альтернативы вы можете попытаться использовать перегрузки (а не специализации) для типов, которые хотите поддерживать ... Если вы одновременно включите ADL, код пользователя станет намного проще. –

+0

где ваша структура с функцией 'static void'? – Walter

+0

@ DavidRodríguez-dribeas: вы правы, я думаю, было бы намного лучше с помощью одной 'конвертера ' struct. Я проверю это, и я дам вам знать, удовлетворен ли я этим, чтобы вы могли опубликовать ответ, который я могу принять. –

ответ

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); 
    } 
}; 
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; 
} 
+0

Я не думаю, что это сработает [потому что у меня есть «резервный» случай, если нет явной специализации] (https://github.com/SuperV1234/SSVUtilsJson/blob/master/include/SSVUtilsJson/Utils /UtilsJson.h#L39). Я прав? –

+0

Это работает только в том случае, если 'T' неявно конвертируется в' Obj', правильно? Поэтому либо просто напишите резервную перегрузку 'Obj conv (Obj const & o) {return o; } 'или написать шаблон свободной функции: это должно быть всегда хуже, чем явно перепечатанная перегрузка. – Useless

+0

Нет, это работает, если 'T' может быть присвоено' Obj', я считаю. Во всяком случае, я пробовал ваше решение, но оно не работает - даже если присутствует «более конкретная» перегрузка, она пытается сопоставить перегрузку 'template ' overload. –

 Смежные вопросы

  • Нет связанных вопросов^_^