Есть ли что-то вроде intern()
a> в C или C++, как в Java? Если нет, как я могу выполнить интернирование строк в C или C++?
Как я могу интернировать строки в C или C++?
Ответы (3)
boost::flyweight< std::string >
кажется именно тем, что вы ищете.
typedef std::hash_set< std::string > StringCache;
даст вам менее причудливую версию того, что вы ищете. Стандартная библиотека C++ очень проста по сравнению с большинством других языков сама по себе.
- person Ylisar; 17.05.2012
boost::flyweight
требует, чтобы объекты были неизменяемыми; это не относится к std::string
. Такие вещи, как []
, скорее всего, вызовут проблемы (или не вызовут, в зависимости от того, как объекты будут использоваться позже).
- person James Kanze; 17.05.2012
boost::flyweight
делает объект неизменяемым, []
не вызовет проблем, потому что boost::flyweight< T >
предоставляет только const T&
.
- person Ylisar; 17.05.2012
Есть ли что-то вроде метода intern() в C, как в Java?
Нет в стандартной библиотеке C.
Если нет, как выполнить интернирование строк в C?
Боюсь, с большим трудом. Первая проблема заключается в том, что «строка» не является четко определенной вещью в C. Вместо этого у вас есть char *
, который может указывать на строку с нулевым завершением или может просто обозначать позицию символа. Тогда у вас возникает проблема, заключающаяся в том, что некоторые строки встроены в другие вещи... или хранятся в стеке. И то, и другое делает интернирование невозможным и/или бессмысленным. Кроме того, существует проблема, заключающаяся в том, что строковые литералы C не гарантированно будут интернированы... так, как это гарантирует Java. Наконец, есть проблема, заключающаяся в том, что интернирование — это ожидающая своего часа утечка памяти... если язык не подвергается сборке мусора.
Сказав это, способ (попытка) реализовать интернирование в C будет заключаться в создании хэш-таблицы для хранения интернированных строк. Вам нужно сделать предварительным условием, что вы не можете интернировать строку, если она не является литералом или строкой, выделенной в своем собственном узле кучи. Чтобы решить проблему утечки памяти, вам потребуется подсчет ссылок для каждой строки, чтобы определить, когда интернированную строку можно отбросить.
Что будет означать интернирование строк в языке с семантикой значений? Интернирование — это механизм принудительной идентификации объекта для ссылок на строки с идентификатором значения. Это актуально для языков, использующих семантику ссылок и использующих идентификатор объекта в качестве функции сравнения по умолчанию. C++ по умолчанию использует семантику значений, а такие типы, как std::string
, не имеют идентичности, поэтому интернирование не имеет смысла.
Некоторые реализации (например, g++) могут использовать форму ссылочной семантики для строковых данных за кулисами. Такая реализация может предложить своего рода интернирование этих данных в качестве расширения. (Насколько я знаю, G++ этого не делает, но автоматически "интернирует" пустые строки.)
Большинство других реализаций даже не используют внутреннюю семантику ссылок. Как бы вы внедрили реализацию, использующую оптимизацию небольших строк (например, MS)? В некоторых случаях данные буквально находятся в классе, а динамически выделяемой памяти нет.