Я выполняю рефакторинг внешнего интерфейса компилятора и сталкиваюсь с проблемой константной переменной, которая необратима для их неконстантного аналога.
Контекст следующий: у меня есть дерево абстрактного синтаксиса ( AST) и таблица символов, которая содержит символы, и я хочу вычислить типы узлов ast и символы в таблице символов. Я буду ссылаться на часть вычисления типа как 'Подсистема'.
Ограничения следующие:
- Моя AST - сложная структура, поэтому я хотел бы избежать итерации по всему узлу каждый раз, когда это возможно.
- Подсистема строится в соответствии с функциональной парадигмой, поэтому она не будет напрямую изменять что-либо (ни AST, ни таблицу символов), а только вычисляет тип и, в конечном итоге, символ, используя таблицу символов. Его параметрами являются текущий узел AST, тип которого должен быть вычислен, и таблица символов.
- Когда подсистема вычислений завершена, я хочу сослаться на возвращенный символ как неконстантный указатель.
Вот (действительно упрощенная) версия того, о чем я говорю:
#include <string>
#include <map>
// For readability / understandability only
using Type = int;
using Symbol = int;
struct TypeSymbol {
Type t;
const Symbol* s;
};
TypeSymbol ComputeTypeSymbolInSubsystem(const std::map<std::string, int>& data) {
return { 123, &data.at("bar") };
}
int main()
{
std::map<std::string, Symbol> symbols = { {"test", 0 } , { "foo", 51 }, { "bar", 63 }, {"", 2 } };
auto typeSymbol = ComputeTypeSymbolInSubsystem(symbols);
// Obvious compilation error, even if "s" is still refering to a mutable memory zone (the symbols variable)
*typeSymbol.s = 1;
return 0;
}
, что приводит к следующей ошибке компиляции в g cc 9.2.0:
main.cpp: In function 'int main()':
main.cpp:25:19: error: assignment of read-only location '* typeSymbol.TypeSymbol::s'
25 | *typeSymbol.s = 1;
| ~~~~~~~~~~~~~~^~~
Проблема в том, что, поскольку таблица символов и AST передаются подсистеме «const», теперь невозможно получить указатель const из возвращенного значения TypeSymbol.
Как я могу вернуться к неконстантный указатель в этом контексте? Я думал об использовании const_cast, но обычно это подразумевает недостаток дизайна, не так ли?