Оператор підпису в std::string_view
std::string_view::operator[]
повертає const_reference, тому ми не можемо змінювати значення.
std::next_permutation()
std::next_permutation()
може бути на 10% швидшим, ніж ваш звичайний підхід для генерації перестановок (комбінаторика). Це також працює для std::string.
substr() для std::string_view
std::string_view::substr()
повертає інший std::string_view
, тому substr() на std::string_view є більш ефективним, ніж на std::string.
Constexpr функція
Константна змінна constexpr гарантує свою наявність під час компіляції, але функція constexpr може бути доступною або недоступною. Також немає параметра constexpr функції, якщо ви маєте намір його використовувати, ймовірно, ви маєте на увазі параметр шаблону цього типу. https://stackoverflow.com/questions/23569309/cant-use-function-parameter-of-a-constexpr-function-in-a-constant-expression
std::vector<> не приймає типи const або volatile
Ви не можете оголосити std::vector як:
std::vector vector;
Інакше ви отримаєте таку помилку:
/usr/include/c++/13/bits/stl_vector.h:440:66: помилка: статична перевірка не пройшла: std::vector має мати тип значення, що не є const або volatile
440 | static_assert(is_same::type, _Tp>::value
У контекстах оцінки шаблонів ви можете позбутися цього повідомлення так:
tempate::type>
void function()
{
// ОК
std::vector v;
}
std::initializer_list<> не має функції-члена data()
Хоча std::initializerlist<> не має функції-члена std::initializerlist<>::data(), C++17 надає безкоштовну функцію std::data()
, яку можна використовувати для отримання вказівника на основні дані.
std::initializer_list initList { 3, 4, 5, 6, 7, 8 };
const int* data = std::data(initList);
dynamic_cast<> не працює в конструкторах при множинному успадкуванні
Динамічне приведення типів працює під час виконання, тому типова інформація недоступна, поки об'єкт не буде побудований. Наприклад, розглянемо наступний випадок:
class MyContainerBase;
void SomePublicFunction(MyContainerBase* base);
class MyContainerBase : public Container, public Scrollable
{
MyContainer()
{
SomePublicFunction(this);
}
};
void SomePublicFunction(MyContainerBase* base)
{
// Це твердження ніколи не спрацює, це означає, що Scrollable ще не побудований.
// Тому dynamic_cast до нього повертає nullptr.
assert(dynamic_cast(base) == nullptr);
}
std::copy з std::ostream_iterator для виведення векторів
// Це не визнається в std::ostream_iterator для типів елементів std::pair<>
template
static std::ostream& operator<<(std::ostream& stream, const std::pair& pair)
{
stream << "{ " << pair.first << ", " << pair.second << " }";
return stream;
}
template
static std::ostream& operator<<(std::ostream& stream, const std::vector& values)
{
stream << "{ ";
for(std::size_t i = 0; const auto& value : values)
{
stream << value;
if(++i < values.size())
stream << ", ";
}
// Використання цього не дозволяє визначити шаблонні аргументи для перевантаження operator<< для std::pair<>
//std::copy(values.begin(), values.end(), std::ostream_iterator(stream, ", "));
stream << " }";
return stream;
}
Порядок зв'язування кількох статичних бібліотек має значення
Лінкер оптимізує символи в статичній бібліотеці, які не використовуються.
Тому якщо статична бібліотека з'являється першою (але після виконуваного файлу) і жоден з її символів не використовується у виконуваному файлі, то лінкер виведе всю бібліотеку.
Перегляд детальних логів gcc
gcc -v main.c -o ./main
std::array<>
Пам'ять для std::array<> автоматично виділяється, і вона не використовує пам'ять купи.
std::copy
std::vector fromVector = ...;
std::vector toVector = ...;
std::copy(fromVector.begin(), fromVector.end(), toVector.begin());
std::vector<>::insert()
std::vector v;
v.insert(v.begin(), srcVector.cbegin(), srcVector.cend());
Хешування std::string_view за допомогою лише size() та data()
https://github.com/ravi688/CrackingTheCodingInterview/commit/afcc99fcacd3da9bfab3c0472580b27025bb59f9 дає на 14% швидші результати в std::unordered_map<>
Конфлікт у висновку шаблонного параметра
Розглянемо наступну функцію
template
static bool findValue(const std::vector& v, const T& v)
{
...
}
Якщо ви викликаєте функцію таким чином, то це призведе до конфлікту в висновку типу
std::vector v;
findValue(v, 5);
Компилятор матиме два висновки типу для одного шаблонного параметра: std::size_t
та int
.
Як це зробити працюючим?
Зробіть так:
template
static bool findValue(const std::vector& v, const T& v)
{
...
}
Перекладено з: [C++ Notes](https://ravi-prakash-singh.medium.com/c-notes-b4c7a2b3aaf3)