К вашему сведению, не все чистые функции могут быть вычислены во время компиляции, и быть чистым не требуется для запуска во время компиляции. На самом деле они имеют мало общего друг с другом.
Оценка функции времени компиляции предпринимается для ЛЮБОЙ функции, но ТОЛЬКО тогда, когда ДОЛЖНА быть. Это определяется контекстом - должен ли быть ответ во время компиляции? Это верно для:
- значения enum
- статические инициализаторы
- статические условия
- статический аргумент foreach
- аргументы шаблона
Если вы хотите получить его во время выполнения, просто вызовите его вне одного из этих контекстов.
static int result = f();
Выше приведен статический инициализатор, то есть CTFE.
static int result;
result = f();
Это больше не статический инициализатор, поэтому нет CTFE. Чтобы он не вызывался дважды, вы можете просто поставить на него обычную проверку if
со специальным значением, означающим, что он еще не запущен, или с отдельным флагом bool.
Если это в области видимости модуля, используйте конструктор:
static int result;
static this() { result = f(); }