#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
похоже, это ответ на большинство проблем с шаблонами: P2. Когда я пытаюсь использовать следующее определение: 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. Я постараюсь их обновить.