Я бы просто использовал тип RAII, чтобы переключать небезопасный флаг внутри области видимости следующим образом:
thread_local bool unsafe_flag = false;
/// RAII Type that toggles the flag on while it's alive
/// Possibly add a reference counter so it can be used nested
struct unsafe_scope
{
constexpr unsafe_scope() { unsafe_flag = true; }
~unsafe_scope() { unsafe_flag = false; }
};
/// Gets a value from a pointer
int get_value(int* ptr)
{
if ( unsafe_flag )
{
if ( ptr == nullptr ) { return 0; }
}
return *ptr;
}
int main()
{
int* x = nullptr;
//return get_value(x); // Doesn't perform the check
{
unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
}
Чтобы сделать его вложенным, я бы добавил счетчик ссылок, подобный этому:
/// RAII Type that toggles the flag on while it's alive
struct unsafe_scope
{
thread_local static size_t ref_count;
constexpr unsafe_scope()
{
unsafe_flag = true;
ref_count++;
}
~unsafe_scope()
{
ref_count--;
if ( ref_count == 0 ) { unsafe_flag = false; }
}
};
/// In source file
thread_local size_t unsafe_scope::ref_count = 0;
ref_count не обязательно должен быть атомарным, поскольку он thread_local
Теперь я не думаю, что есть способ достичь желаемого синтаксиса с помощью unsafe
перед областью действия, но если вы поставитеоно сразу после области видимости должно быть примерно таким же:
{ unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
Редактировать:
Я заметил, что ответ Квентина также является типом RAII, только с немного другой семантикой,вместо того, чтобы иметь глобальный флаг thread_local, функция просто возвращает, если счетчик ссылок больше 0. Также макрос достигает точного синтаксиса, который вы хотели, хотя это также возможно с этим unsafe_scope
, изменяя его макрос следующим образом:
#define unsafe\
if (unsafe_scope cur_scope; false) {} else
Его метод использует инициализатор if в C ++ 17, который позволяет вам инициировать переменную в операторе if, но переменная по-прежнему инициализируется в блоке else, поэтому яТ будет уничтожен только после остальной области видимости, если закончится.