C++: итерация по списку универсального типа

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

Используя точные определения классов Вы дали, вот отображения:

public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.ItemId);
        Map(x => x.ItemType);
        Map(x => x.FieldA);

        AddPart(new ConcreteItemYMap());
    }
}

public class SubItemMap : ClassMap<SubItem>
{
    public SubItemMap()
    {
        WithTable("Item");

        // Get the base map and "inherit" the mapping parts
        ItemMap baseMap = new ItemMap();
        foreach (IMappingPart part in baseMap.Parts)
        {
            // Skip any sub class parts... yes this is ugly
            // Side note to anyone reading this that might know:
            // Can you use GetType().IsSubClassOf($GenericClass$)
            // without actually specifying the generic argument such
            // that it will return true for all subclasses, regardless
            // of the generic type?
            if (part.GetType().BaseType.Name == "JoinedSubClassPart`1")
                continue;
            AddPart(part);
        }
        Map(x => x.FieldB);
        AddPart(new ConcreteItemXMap());
    }
}

public class ConcreteItemXMap : JoinedSubClassPart<ConcreteItemX>
{
    public ConcreteItemXMap()
        : base("ItemId")
    {
        WithTableName("ConcreteItemX");
        Map(x => x.FieldC);
    }
}

public class ConcreteItemYMap : JoinedSubClassPart<ConcreteItemY>
{
    public ConcreteItemYMap()
        : base("ItemId")
    {
        WithTableName("ConcreteItemY");
        Map(x => x.FieldD);
    }
}

Те отображения производят два файла hbm.xml как так (некоторые посторонние данные, удаленные для ясности):

  <class name="Item" table="`Item`">
    <id name="ItemId" column="ItemId" type="Int32">
      <generator class="identity" />
    </id>
    <property name="FieldA" type="String">
      <column name="FieldA" />
    </property>
    <property name="ItemType" type="String">
      <column name="ItemType" />
    </property>
    <joined-subclass name="ConcreteItemY" table="ConcreteItemY">
      <key column="ItemId" />
      <property name="FieldD">
        <column name="FieldD" />
      </property>
    </joined-subclass>
  </class>

  <class name="SubItem" table="Item">
    <id name="ItemId" column="ItemId" type="Int32">
      <generator class="identity" />
    </id>
    <property name="FieldB" type="String">
      <column name="FieldB" />
    </property>
    <property name="ItemType" type="String">
      <column name="ItemType" />
    </property>
    <property name="FieldA" type="String">
      <column name="FieldA" />
    </property>
    <joined-subclass name="ConcreteItemX" table="ConcreteItemX">
      <key column="ItemId" />
      <property name="FieldC">
        <column name="FieldC" />
      </property>
    </joined-subclass>
  </class>

Это ужасно, но похоже, что это могло бы генерировать применимый файл отображения, и это Быстро!:/Вы могли бы быть в состоянии настроить идею еще немного для получения точно, что Вы хотите.

5
задан mahju 15 October 2009 в 09:39
поделиться

3 ответа

Конечно, это должно сработать, но похоже, что у вас работает либо одно, либо оба из перечисленных ниже.

  • Иметь Q параметр шаблона или тип, который так или иначе зависит от него (typedef для него). Затем поместите typename перед std :: list , чтобы компилятор знал, что :: iterator является типом, и мог правильно продолжить анализ (это может быть статический член значения). Зная, что это тип, компилятор может произвести лучшую диагностику для определений шаблонов, и вы должны определить, является ли это типом, используя typename .
  • Иметь событий константным списком. Затем используйте const_iterator .

Обновление : показанная ошибка компиляции несомненно указывает на то, что первая точка верна: Q прямо или косвенно зависит от параметра шаблона, и вы должны указать typename следующим образом:

typename std::list< Event<Q> >::iterator it;

Компилятор считает, что это не тип, поэтому он требует какой-то оператор или точка с запятой после :: iterator (например, умножение). Введите typename , чтобы он знал, что вместо этого он называет тип.

Обновление : см. Часто задаваемые вопросы о шаблоне , чтобы узнать об аналогичных проблемах с шаблоном и решениях.

См. Часто задаваемые вопросы о шаблоне для получения информации об аналогичных проблемах с шаблоном и их решениях.

См. Часто задаваемые вопросы о шаблоне для получения информации об аналогичных проблемах с шаблоном и их решениях.

8
ответ дан 14 December 2019 в 04:42
поделиться

в вашем примере, что такое S?

list<Event<S> >::iterator it; // what is S 
for (it = events.begin(); it != events.end(); it++) { ... }

вы можете попробовать поместить туда собственный тип?

list<Event<int> >::iterator it; 
for (it = events.begin(); it != events.end(); it++) { ... }

или упростить его еще больше?

list<int>::iterator it; 
for (it = events.begin(); it != events.end(); it++) { ... }
0
ответ дан 14 December 2019 в 04:42
поделиться

Вы импортировали пространство имен std? Должно быть объявление итератора было:

std::list<Event<S> >::iterator it;
0
ответ дан 14 December 2019 в 04:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: