C ++ замена переменных-членов значениями из других типов - PullRequest
2 голосов
/ 23 декабря 2011

У меня есть класс T с n переменными-членами, например

class T{
  ushort name;
 ushort id;
 double value;
.....etc...
};

У меня также есть коллекция классов T1, T2 ...., каждая из которых состоит из переменных-членов, которые являются подмножествами переменных-членовT (из-за отсутствия лучшего слова, позвольте мне назвать это подмножество типа T).Например, T1 может быть

class T1 {
 ushort name;
 double value;
};

, который просто выбирает два члена T.

Я хотел бы написать метод

template <typename X> 
T join(T t, X x)

, где мы возвращаемкласс типа T путем замены значений каждой переменной-члена в t значениями x (при условии, что X является подтипом T), а другие значения t остаются прежними.

Я могу думать оделать это через специализации.Но должен быть элегантный способ сделать это (возможно, определить, когда тип X является подмножеством типа T, и делать правильные вещи).

Ответы [ 4 ]

0 голосов
/ 18 апреля 2012

Я бы реализовал преобразование из T1 ... Tn в T (или некоторый класс, производный от T и имеющий информацию о том, какие члены на самом деле установлены), а затем реализовал функцию join () в терминах T. на самом деле это хорошее место для магии шаблонов

0 голосов
/ 23 декабря 2011

Если вы не хотите предоставлять специализации для всех типов подмножеств.Вы можете попробовать использовать идиому детектора членов: Member Detector или __ if_exist , если вы используете MSVC.Поэтому вам нужно всего лишь написать [количество членов в макросах T] * 2 (и если вы используете MSVC, вам не нужен SetXXX) вместо того, чтобы специализировать все возможные комбинации членов в T

CREATE_MEMBER_DETECTOR(name);
CREATE_MEMBER_DETECTOR(id);
CREATE_MEMBER_DETECTOR(value);
......

template<int N, typename T, typename R>
class SetName
{ 
public:
   void operator()(T& t, R& r)
   {
   }
};

template<typename T, typename R>
class SetName<1, T, R>
{
public:
   void operator()(T& t, R& r)
   {
      t.name = r.name;
   }
};
......
(can be macros too)

Иобъединение () должно быть:

template <typename SUBSET> 
T join(T t, SUBSET x)
{
   SetName<Detect_name<SUBSET>::value, T, SUBSET>()(t, x);
   SetValue<Detect_value<SUBSET>::value, T, SUBSET>()(t, x);
   ......

   return t;
}
0 голосов
/ 18 апреля 2012

Попробуйте это:

#include <iostream>
#include <typeifo>

using namespace std;

template<typename T>
struct SetBase
{
    T first;
    T second;
    SetBase(const T& first = T(), const T& second = T()) 
    : first(first), second(second)    {}
};

template<typename T>
struct Set : public SetBase<T>
{
   short name_id;
   Set(const T& first = T(), const T& second = T(), const short& name) :
   SetBase<T>(first, second), name_id(name){}
};

template<typename Class, typename BaseClass>
Class* join(Class **a, BaseClass *b)
{
    if(typeid(Class) != typeid(BaseClass))
    {
        Class* retval = new Class(*static_cast<Class*>(b));
        retval->name_id = (*a)->name_id;
        *a = retval;
    }
    else
    {
        Class* retval = new Class(*b);
        *a = retval;
    }
    return retval;
}

int main()
{
    Set<int> *a = new Set<int>(1, 2, 3);
    SetBase<int> *b = new SetBase<int>(4, 5);
    cout << join(&a, b)->first << " " << join(&a, b)->second << " " << join(&a, b)->name_id << "\n";
    cout << a->first << " " << a->second << " " << a->name_id << "\n";

    return 0;
}

Класс Set является общедоступным производным от SetBase, поэтому используемый мной приведенный тип допустим

0 голосов
/ 23 декабря 2011

Я могу думать об этом через специализации.Но должен быть элегантный способ сделать это (возможно, определить, когда тип X является подмножеством типа T, и делать правильные вещи).

«Определение» является частью специализации.Вы должны предоставить специализации для «подмножеств» -типов и не предоставлять реализацию для общей специализации (чтобы спровоцировать ошибку компиляции, когда кто-то использует другие типы с этим методом).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...