В основном я хочу, чтобы в моем коде это было:
Engine.getById(WSID('some-id'));
Что должно быть преобразовано
Engine.getById('1a61bc96');
непосредственно перед компиляцией в asm. Итак, во время компиляции.
Это моя попытка
constexpr int WSID(const char* str) {
boost::crc_32_type result;
result.process_bytes(str,sizeof(str));
return result.checksum();
}
Но я получаю это при попытке скомпилировать с MSVC 18 (CTP, ноябрь 2013 г.)
error C3249: illegal statement or sub-expression for 'constexpr' function
Как я могу получить функцию WSID
, используя этот или любой другой способ, если это выполняется во время компиляции?
Пробовал это: Хеширование строки времени компиляции
warning C4592: 'crc32': 'constexpr' call evaluation failed; function will be called at run-time
РЕДАКТИРОВАТЬ:
Впервые я услышал об этой технике в Game Engine Architecture от Джейсона Грегори. Я связался с автором, который мне любезно ответил:
Что мы делаем, так это пропускаем наш исходный код через специальный небольшой препроцессор, который ищет текст в форме
SID('xxxxxx')
и преобразует все, что находится между одинарными кавычками, в его хешированный эквивалент в виде шестнадцатеричного литерала (0xNNNNNNNN
). [...]Вы могли бы сделать это с помощью макроса и / или некоторого метапрограммирования шаблона, хотя, как вы говорите, сложно заставить компилятор выполнять такую работу за вас. Это не невозможно, но написать собственный инструмент проще и гибче. [...]
Также обратите внимание, что мы выбрали одинарные кавычки для
SID('xxxx')
литералов. Это было сделано для того, чтобы мы могли получить разумную подсветку синтаксиса в наших редакторах кода, но если что-то пойдет не так и какой-то необработанный код когда-либо передаст его компилятору, он выдаст синтаксическую ошибку, потому что одинарные кавычки обычно зарезервированы для односимвольные литералы.Также обратите внимание, что очень важно, чтобы ваш маленький инструмент предварительной обработки кэшировал строки в какой-либо базе данных, чтобы можно было искать исходные строки с помощью хэш-кода. Когда вы отлаживаете свой код и проверяете переменную
StringId
, отладчик обычно показывает вам довольно непонятный хэш-код. Но с базой данных SID вы можете написать плагин, который преобразует эти хэш-коды обратно в их строковые эквиваленты. Таким образом, вы увидите SID ('foo') в окне просмотра, а не0x75AE3080
[...]. Кроме того, игра должна иметь возможность загружать ту же базу данных, чтобы она могла выводить на экран строки вместо шестнадцатеричных хэш-кодов для целей отладки [...].
Но хотя препроцесс имеет некоторые основные преимущества, это означает, что мне нужно подготовить какую-то систему вывода измененных файлов (они будут храниться в другом месте, а затем нам нужно сообщить MSVC). Так что это может усложнить задачу компиляции. Есть ли способ предварительно обработать файл с помощью Python, например, без головной боли? Но вопрос не в этом, и меня все еще интересует использование функции времени компиляции (в отношении кеша я мог бы использовать индекс идентификатора)
constexpr
. Если вы действительно хотели сделать это время компиляции, вам придется немного подправить шаблон ... - person Nim   schedule 23.02.2015std::string const&
является буквальным типом (поскольку он является ссылкой) и, следовательно, разрешен в качестве типа для параметра функции функции constexpr. clang ++ и g ++ также принимают его (в режиме C ++ 11). - person dyp   schedule 23.02.2015