Свойства

  • Модифицируемость (mutability) параметров в шаблонах указывает, могут ли передаваемые аргументы быть изменены внутри функции или класса.
  • Константность (constness) параметров гарантирует, что передаваемые аргументы не будут изменены. Использование const позволяет защитить данные от непреднамеренных изменений.
  • Перемещаемость (moveability) параметров позволяет передавать владение ресурсами временных объектов, избегая ненужного копирования, что улучшает производительность.

Рекомендации

Модифицируемость

  • Используйте ссылки (&), чтобы передавать параметры по ссылке и изменять их внутри функции.
  • Избегайте лишних копирований, работая с оригинальными данными.

Константность

  • Используйте const для параметров, которые не должны изменяться внутри функции.
  • Это улучшает безопасность кода и делает его более понятным.

Перемещаемость

  • Используйте rvalue-ссылки (&&) для временных объектов.
  • Применяйте std::move для передачи владения ресурсами.
  • Убедитесь, что исходный объект больше не используется после перемещения.

Примеры кода

Модифицируемость

#include <iostream>
#include <vector>
 
template<typename T>
void modifyVector(std::vector<T>& vec) {
    vec.push_back(T());
    std::cout << "Vector modified, size: " << vec.size() << std::endl;
}
 
int main() {
    std::vector<int> myVec = {1, 2, 3};
    modifyVector(myVec);  // Модифицируемый аргумент
    return 0;
}

Константность

#include <iostream>
#include <vector>
 
template<typename T>
void printVector(const std::vector<T>& vec) {
    for (const auto& elem : vec) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
}
 
int main() {
    std::vector<int> myVec = {1, 2, 3};
    printVector(myVec);  // Константный аргумент
    return 0;
}

Перемещаемость

#include <iostream>
#include <vector>
#include <utility>
 
template<typename T>
void processVector(std::vector<T>&& vec) {
    std::vector<T> localVec = std::move(vec);  // Перемещение ресурса
    std::cout << "Vector size: " << localVec.size() << std::endl;
}
 
int main() {
    std::vector<int> myVec = {1, 2, 3, 4, 5};
    processVector(std::move(myVec));  // Передача временного объекта
    return 0;
}

Комбинирование свойств

В шаблонных функциях можно комбинировать свойства для обеспечения гибкости и эффективности:

#include <iostream>
#include <utility>
 
template<typename T>
void process(T&& arg) {
    if constexpr (std::is_lvalue_reference_v<T>) {
        std::cout << "Lvalue reference\n";
        // Работаем с lvalue
    } else {
        std::cout << "Rvalue reference\n";
        // Работаем с rvalue
    }
}
 
int main() {
    int x = 10;
    process(x);  // Передача lvalue
    process(20); // Передача rvalue
    return 0;
}

Использование этих свойств позволяет писать более гибкий, эффективный и безопасный код.