Как позволить шаблонной функции иметь друга (-как) доступ?

Существует одна BEXTR (Извлечение битового поля (с регистром)) x86 для процессоров Intel и AMD и UBFX для ARM. Существуют встроенные функции, такие как _bextr_u32() (ссылка требует входа в систему), которые позволяют явно вызывать эту инструкцию.

Они реализуют код (source >> offset) & ((1 << n) - 1) C: получить n непрерывных битов из source, начиная с бита offset. Вот полное определение функции, которая обрабатывает крайние случаи:

#include 

unsigned getbits(unsigned value, unsigned offset, unsigned n)
{
  const unsigned max_n = CHAR_BIT * sizeof(unsigned);
  if (offset >= max_n)
    return 0; /* value is padded with infinite zeros on the left */
  value >>= offset; /* drop offset bits */
  if (n >= max_n)
    return value; /* all  bits requested */
  const unsigned mask = (1u << n) - 1; /* n '1's */
  return value & mask;
}

Например, чтобы получить 3 битов из 2273 (0b100011100001), начиная с 5 -го бита, вызовите getbits(2273, 5, 3) - он извлекает 7 (0b111).

Например, скажем, я хочу первые 17 бит 32-битного значения; что мне делать?

unsigned first_bits = value & ((1u << 17) - 1); // & 0x1ffff

Предположим, что CHAR_BIT * sizeof(unsigned) равно 32 в вашей системе.

Я предполагаю, что должен использовать оператор модуля, и я попробовал его и смог получить последние 8 бит и последние 16 бит

unsigned last8bitsvalue  = value & ((1u <<  8) - 1); // & 0xff
unsigned last16bitsvalue = value & ((1u << 16) - 1); // & 0xffff

Если смещение всегда ноль, как во всех ваших примерах в вопросе, тогда вам не нужно более общее getbits(). Существует специальная инструкция процессора BLSMSK, которая помогает вычислять маску ((1 << n) - 1) .

12
задан CW Holeman II 3 August 2015 в 05:20
поделиться

3 ответа

Если вы хотите, чтобы функция шаблона была другом, вы должны сказать это в объявление класса. Измените строку, объявляющую функцию друга, на следующую:

template <typename T> 
friend int ask_runUI(T& a_ui);

Теперь, если ваш класс сам является шаблоном, все становится намного сложнее. Друзья по шаблонам - задача не из простых. Для этого я отсылаю вас к тому, что говорится по этому поводу в C ++ FAQ Lite .

31
ответ дан 2 December 2019 в 04:53
поделиться

У меня это сработало!

class AskBase {
public:
    AskBase(){}
    template<typename T> 
    friend int ask_runUI(T& a_ui);
private:
    static int const    s_EOF = -99;
    static int const    s_BACKUP = -1;
    static int const    s_NULL = 0;
    static int const    s_OK = 1;
};
//int ask_runUI()
template<typename T> 
int ask_runUI(T& a_ui)
{
    return AskBase::s_NULL;
}
2
ответ дан 2 December 2019 в 04:53
поделиться

Самым простым, вероятно, является замена static int const члены с перечислением и не связываться с friend s:


class AskBase {
public:
    enum { Eof = -99, Null = 0, Ok = 1, Backup = -1 };
    ...
};
-2
ответ дан 2 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: