Разрешено ли компилятору пропустить комбинированный вызов операторов & * для указателя? - PullRequest
2 голосов
/ 24 января 2020

У меня есть эта шаблонная функция

template <typename T, typename It, std::enable_if_t<std::is_integral<T>::value, int> = 0>
inline T decode(It &it) {
    static_assert(std::is_same<typename std::iterator_traits<It>::value_type, std::uint8_t>::value, "invalid");
    T* v_p = reinterpret_cast<T*>(&*it);
    it += sizeof(T);
    return *v_p;
}

, которая используется для декодирования целых чисел из необработанного указателя. Функцию можно использовать с любым типом, имеющим черты итератора, то есть либо указатели на std::uint8_t, либо итераторы на std::uint8_t контейнеры STL с итераторами, которые удовлетворяют LegacyContiguousIterator требованиям.

Функция работает , но я не уверен насчет производительности вызова &*it, когда it является указателем. Операторы необходимы для получения указателя от итератора, как объяснено в этом ответе , но для указателей POD это кажется излишним. Разрешено ли компилятору просто отбрасывать операции или лучше написать специализацию для указателей

Ответы [ 3 ]

6 голосов
/ 24 января 2020

Для указателя , тогда да из-за , как если бы правило позволяло это.

Но in в этом случае, если it не указатель, а объект с перегруженным оператором разыменования, компилятор не может этого сделать.

0 голосов
/ 24 января 2020

В этом случае неправильно , потому что вы используете итератор, который не является указателем, а является только объектом, у которого есть оператор разыменования , поэтому правило базового c действительно в этом случае указатели не могут быть применены.

Для получения дополнительной информации см. AS-IF-RULE

0 голосов
/ 24 января 2020

Если it является указателем, то &* будет oop.

Но, в любом случае, всякий раз, когда вы заявляете что-то вроде:

I Я не уверен в производительности [...]

Вам действительно нужно уметь измерить разницу. Если вы не можете, вы, вероятно, ни о чем не беспокоитесь.

...