#c #templates #template-specialization #specialization
#c #шаблоны #шаблон-специализация #специализация
Вопрос:
Я хотел бы специализировать шаблон для двух типов, которые основаны на одном и том же базовом типе:
using myint=uint16_t; //16 bit integer
using myfxpt=uint16_t //8 8 bit fix point number
Невозможно специализировать шаблон для обоих, потому что оба являются uint16_t
. Однако, согласно представлению, они все еще различаются.
Как я мог бы найти обходной путь для этой проблемы? Использование как-то прозрачного класса fixpoint также может быть решением, но важна эффективность. Я не знаю, как я мог бы написать это так, чтобы после оптимизации компилятора мы получили тот же результат.
Комментарии:
1. Можете ли вы использовать
struct FixPtStruct { uint16_t fp; };
?2.
myint
Иmyfxpt
в настоящее время являются одними и теми же типами. Это просто псевдонимы с разными именами одного и того же типа. Вам нужно, чтобы типы отличались. Дляmyfxpt
вы можете использовать вместо этого структуру с подходящим API-интерфейсом, которая имеет те же операции для сложения, что иunit16
, но разные для умножения, чтобы соответствовать ее точечной природе.3. Для удобства обслуживания я хотел бы использовать тип, как если бы это был базовый тип. Я мог бы определить несколько функций, таких как присваивание
fxpt = myconst
и другие операторы, но я все еще не знаю, насколько эффективным будет конечный код. И даже, мне нужно только сложение и вычитание, поэтому встроенного в решение компилятора будет достаточно. Просто обработка этих данных должна быть другой. (например, отображение значения)4. boost имеет строгий typedef
5. но я все еще не знаю, насколько эффективным будет конечный код , такой же, как примитивный тип того же размера, с включенной оптимизацией.
Ответ №1:
Что вам нужно, так это строгие определения типов. В C их нет. Были сделаны различные предложения по их добавлению, но они поднимают вопросы, на которые нет четких решений. На данный момент один из способов подделать его — использовать классы enum:
enum class myfxpt : uint16_t {};
constexpr myfxpt operator (myfxpt lhs, myfxpt rhs) noexcept {
return myfxpt{static_cast<uint16_t>(lhs) static_cast<uint16_t>(rhs)};
}
constexpr myfxpt operator-(myfxpt lhs, myfxpt rhs) noexcept {
return myfxpt{static_cast<uint16_t>(lhs) - static_cast<uint16_t>(rhs)};
}
// Same for all the operators you care about. Same for myint. Maybe use macros?
Написанный таким образом, для всех уровней оптимизации выше -O0
любой компилятор будет оптимизировать операции, как если бы они были непосредственно для базового типа.