#c #templates
Вопрос:
У меня есть функция шаблона, которая делает что-то в зависимости от типа, переданного в качестве аргумента шаблона:
templatelt;class Tgt; void foo() { if constexpr (std::is_integral_vlt;Tgt;) { // ... } else if constexpr ... { // ... } }
Проблема в том, что мне на самом деле не нужно создавать экземпляр функции для каждого возможного интегрального типа (чтобы избежать раздувания кода шаблона), поэтому я хотел бы иметь только один экземпляр, который принимает int
и, если мы передадим тип char
или short
он вызовет int
версию. Я бы хотел что-то вроде этого:
templatelt;class Tgt; void foo() { if constexpr (std::is_same_vlt;T, intgt;) { // Only check for `int`, because "lower" types will be converted to int // ... } else if constexpr ... { // ... } } foolt;shortgt;(); // Call `foolt;intgt;` foolt;chargt;(); // Call `foolt;intgt;` foolt;intgt;(); // Call `foolt;intgt;`
Может быть, я могу обернуть функцию внутри структуры и получить structlt;chargt;
функцию, которая расширяет structlt;intgt;
?
Обратите внимание, что нигде нет «значений», у меня есть только параметры шаблона.
Комментарии:
1. Хорошо, и что? В чем заключается ваш вопрос? Ты пробовал то, что предложил? Что случилось?
2. Вы могли бы сделать
jojolatino::is_sameish_vlt;T, intgt;
это с помощью условного поведения, которое вы хотите.3. Вы пробовали использовать
std::is_convertible_vlt;T, intgt;
?4. @Eljay, Но для этого потребуется создать экземпляр a
foolt;Tgt;
для каждого владения T5. @SamVarshavchik Я не пытался использовать
structlt;chargt;
то , что наследуетstructlt;intgt;
, я думаю, это может сработать, как вы думаете? Я просто раскрываю свою проблему и решение, о котором я думал, но я не знаю, упускаю ли я лучшее решение
Ответ №1:
Вы можете превратиться foo
в вызываемый объект и использовать using
псевдоним для выбора различных экземпляров в соответствии T
, например:
#include lt;type_traitsgt; templatelt;class Tgt; struct foo { void operator()() { if constexpr (std::is_same_vlt;T, intgt;) { // ... } else if constexpr ... { // ... } } }; templatelt;class Tgt; auto bar = std::conditional_tlt;std::is_integral_vlt;Tgt;, foolt;intgt;, foolt;Tgt;gt;(); int main() { barlt;shortgt;(); // Call `foolt;intgt;` barlt;chargt;(); // Call `foolt;intgt;` barlt;intgt;(); // Call `foolt;intgt;` barlt;const char*gt;(); // Call `foolt;const char*gt;` }