Свойства
- Модифицируемость (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;
}Использование этих свойств позволяет писать более гибкий, эффективный и безопасный код.