Как получить доступ к typedefs из унаследованного шаблона

#c #templates #g

#c #шаблоны #g

Вопрос:

У меня есть следующий фрагмент кода:

 template <typename T>
struct ChildStruct
{
  typedef std::map<int,T> Tmap;
};

struct DataStruct: public ChildStruct<long>
{

};

void Test()
{
  DataStruct::ChildStruct<long>::Tmap map;
}
  

Возможно ли получить доступ к typedef Tmap, расположенному в дочерней структуре, извне DataStruct без определения типа этой дочерней структуры внутри Datastruct?

Когда я использую упомянутый фрагмент кода в Visual Studio, все работает нормально, но linux / macos g выдает ошибку:

 error: 'ChildStruct' is not a member of 'DataStruct'
  

Я нашел способ, определив вспомогательный typedef внутри od DataStruct:

 struct DataStruct: public ChildStruct<long>
{
    typedef ChildStruct<long> ChildStructLong;
};

void Test()
{
    DataStruct::ChildStructLong::Tmap map;
}
  

Но я бы предпочел способ без определения ChildStructLong.

Спасибо!

Отредактировано:

Решением является вызов ChildStruct непосредственно из DataStruct, как предлагает Кристиан Рау. Иногда самое простое решение — лучшее решение 😉

Комментарии:

1. Почему бы просто не использовать ChildStruct<long>::Tmap (без предыдущего DataStruct )?

2. Вы правы ;-). Я не понимал, что это может быть достигнуто таким образом. Спасибо.

Ответ №1:

Используйте следующее:

 typename Foo<double>::my_typedef blah;
  

Комментарии:

1. typename похоже, это ответ на большинство проблем с шаблонами: P

2. Когда я пытаюсь использовать следующее определение: void Test() { typename DataStruct::дочерняя структура<long>::Карта Tmap; } компилятор выдает мне эту ошибку: ошибка C2899: typename не может использоваться вне объявления шаблона

3. Зачем вам здесь нужно имя типа? Вложенный typedef не зависит ни от какого параметра шаблона

4. @Xeo Смотрите часть вопроса: «Возможно ли получить доступ к typedef Tmap, расположенному в дочерней структуре, извне DataStruct без определения типа этой дочерней структуры внутри Datastruct?» Это правда, ему ничего не должно быть нужно, находясь внутри объекта, но за его пределами…

Ответ №2:

Почему вы не используете DataStruct::Tmap напрямую?

 #include <map>

template <typename T>
struct A
{
  typedef std::map<int, T> map_type;
};

struct B : A<int>
{ };

int main()
{
  B::map_type x;
}
  

Посмотрите, как это работает здесь.

Комментарии:

1. Потому что в моем реальном приложении структура B определяется следующим образом: A<Object_One>, A<Object_two>, … поэтому мне нужно указать, какой из типов мне нужен. Но ответ заключается в том, чтобы использовать напрямую<Object_one> без B :: . Я не понимал, что это простое решение.

2. Ну что ж, вы могли бы упомянуть об этом 🙂 Только одно: первый фрагмент кода в вашем вопросе отлично работает с gcc 4.5.0 и выше (тестировался с 4.6 и 4.7).

3. спасибо за замечание. Я проверил свои версии, и это 4.4.5 в Linux и 4.2.1 в macOS. Я постараюсь их обновить.