C ++ не подходит для этого, к сожалению. Вам нужна гораздо более мощная система типов.
Обратите внимание, что даже если бы вы могли, , вы, вероятно, замедлили бы свою программу : целочисленное сравнение намного дороже, чем вызов функции через указатель. Тем более, что ваш процессор может выполнять прогнозирование: он начнет запускать код, как если бы он прошел проверку, и если он закончится с ошибкой, он может отказаться от всего, что делал.
Но обратите внимание, ваш компилятор умен. Например, если у нас есть это:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <vector>
void process(std::vector<int>& data)
{
for (unsigned i = 0; i < data.size(); ++i)
{
int v = data.at(i);
std::cout << v << std::endl;
}
}
int main()
{
try
{
std::vector<int> data;
std::generate_n(std::back_inserter(data), std::rand() + 1, std::rand);
process(data);
}
catch (...)
{
std::cerr << "nope.avi" << std::endl;
}
}
И если мы скомпилируем с g++ -O3
, не будет кода проверки границ . Действительно, компилятор пришел к выводу, что проверка внутри at()
никогда не пройдет (что затем выдает), поэтому он удалил этот код. Таким образом, вы можете оставить проверки границ, и ваш компилятор все равно может их убрать. Тем не менее, обратите внимание, что в более сложных случаях компилятору будет слишком сложно доказать это, поэтому вы заплатите за это.
Это тот тип оптимизаций, который вы могли бы гарантировать с помощью более выразительной системы типов, но компилятор может выполнить их в любом случае. Я не знаю о MSVC; как правило, он не такой умный, но вы можете проверить.
Лучше всего идти по маршруту std::vector<>
: предоставьте непроверенный operator[]
и проверенный at()
. Пусть пользователь вашего класса решит, нужны ли ему чеки.