У меня есть шаблон action
, который принимает любой контейнер STL C
. Однако содержащиеся в нем предметы (C::value_type
) должны быть либо ClassA
, либо ClassB
. До сих пор так хорошо:C++ 11: Специализировать/ограничивать метод в зависимости от значения_таблицы контейнера
struct Whatever {
template<typename C>
void action(const C& c) {
static_assert(std::is_same<typename C::value_type, ClassA>::value ||
std::is_same<typename C::value_type, ClassB>::value,
"Wrong C::value_type");
// do something with c
}
};
// Usage:
Whatever w;
w.action(std::vector<ClassA>{1, 2, 3});
w.action(std::unordered_set<ClassB>{1, 2, 3});
Примечание: класс вшита является не шаблон, единственный шаблон это очень action
метод.
Теперь, в зависимости от C::value_type
, я хочу специализироваться на поведении метода. Вы догадались, вот где мой мозг начинает таять.
Я считаю SFINAE это путь, но, очевидно, я слишком ржавым, чтобы заставить его работать правильно: после нескольких часов, тонны помощника structs
и слишком много кофе для собственного здоровья, компилятор просто продолжает кричать обычные 500 + шаблонные ошибки у меня. Нет смысла копировать либо моего помощника structs
, либо ошибки здесь, это почти бесполезный барахло.
Тем не менее, я должен признать, что я не поддерживал связь со всеми вариантами шаблонов C++ (r) (или даже использовал SFINAE), начиная с хорошего десятилетия, поэтому неудивительно, что я так сильно терпеть неудачу ,
Я сильно подозреваю, что C++ 11 теперь имеет простые, готовые к использованию инструменты, подобные SFINAE, для достижения того, что я хочу, но я даже не знаю, с чего начать поиск в документации. Поисковые системы тоже не помогли, для меня просто слишком много новой информации, чтобы я мог понять, что не имеет отношения к моей проблеме.
Поскольку я в полной потери, я просто принять шаги ребенка и спросить SO ... Мой вопрос заключается в два раза:
- Как можно специализировать поведение метода в зависимости на фактическом типе
C::value_type
с использованием современных инструментов шаблонов C++ 11? - Возможно, есть стандартный способ проверить, действительно ли
C
является контейнером?
Благодарим за внимание.
Ой, глупый меня ... Я * должен * думал об этом, но я искал в таком направлении, противоположном, что я вероятно, никогда не было бы. O_o Большое спасибо! Это, безусловно, отличный ответ на первую часть моего вопроса, очень прямолинейный. – syam
@syam: См. Редактирование. Он ссылается на решение второй части вашего вопроса. – Nawaz
Еще раз спасибо, вы прибили его. Хотел бы я снова поддержать тебя. ;) – syam