2015-07-15 4 views
1

Учитывая следующие классы:Получить Тип Родителя

template <typename T> 
class Child : public T {}; 

У меня также есть Шаблонные функции:

template <typename T> 
void foo(const T& bar) 

После выполнения некоторой гимнастики шаблона У меня есть фрагмент кода, который определил, что bar - Child. Но мне нужно найти , что сортировать.

Я хочу иметь возможность позвонить по bar, что дает тип унаследованного. Так поддельная синтаксис, чтобы найти тип Parent будет:

decltype(foo.parent) bar; 

Есть ли фактический синтаксис для достижения этой цели?

+1

и если ребенок наследует как от родителя 1, так и от родителя2? –

+1

Не могли бы вы описать, что вы пытаетесь достичь посредством такой декларации? Это может помочь вам дать больше указания о том, как сделать что-то в этом роде. – Shrewd

+1

... и если это «Ребенок: Родитель: Дедушка»? – Barry

ответ

1

В соответствии с просьбой ОП, вот расширенная версия моего комментария выше:

Один общий способ обработки этого, если Child и его братья и сестры под вашим контролем является добавление вложенного типа к ним:

template<typename T> class Child : public T 
{ 
public: 
    using parent = T; 
}; 

template<typename T> void foo(const T& bar) 
{ 
    typename T::parent goo; 
} 

Если T не доступно напрямую (в лямбда, например), то это должно работать:

auto foo2 = [](const auto& bar) 
{ 
    typename std::remove_reference_t<decltype(bar)>::parent goo; 
}; 

Для того, чтобы сделать его немного лучше и короче,

template<typename T> using parent = typename T::parent; 

template<typename T> void foo(const T& bar) 
{ 
    parent<T> goo; 
} 

auto foo2 = [](const auto& bar) 
{ 
    parent<std::remove_reference_t<decltype(bar)>> goo; 
}; 

(Хотя parent является относительно общее название; остерегайтесь столкновений. parent_t, возможно?)

Для типов, которые не находятся под вашим контролем, если набор типов известен, parent<T> также может быть признаком внешнего типа.

1

Просто тип в качестве аргумента:

template <typename T> 
void foo(const Child<T>& bar) { 

} 

bar является Child, который наследует от T. Вы даже можете добавить отдельную перегрузку для не Child:

template <typename NonChild> 
void foo(const NonChild& baz) { } 
+0

Да, это то, что я изначально имел, но мне нужна функция, чтобы иметь возможность принимать и другие типы, а не только «Ребенок». (Я знаю, что эта вещь нуждается в перезаписи, но до тех пор, пока я не смогу это сделать;) есть ли что-нибудь, что можно сделать за пределами простого принятия типа в качестве параметра функции? –

+0

@JonathanMee Вот для чего нужна перегрузка. В противном случае уточните, что вы хотите сделать так, чтобы вам нужна одна функция, которая нуждается в 'T' in' Child '* и * работает для не-ребенка. – Barry

+0

Да, это, вероятно, правильное решение. Я собираюсь держаться немного, прежде чем принять, хотя в надежде, что у кого-то есть другая магия. –

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