Специализированный шаблон C для разных, но все еще одинаковых типов

#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 любой компилятор будет оптимизировать операции, как если бы они были непосредственно для базового типа.