constexpr не работает / применяется внутри вызова функции - PullRequest
0 голосов
/ 24 августа 2018

Я реализовал хеш-функцию constexpr времени компиляции, которая отлично работает (т.е. оценивается во время компиляции), если вызывается как

constexpr auto hash = CompileTimeHash( "aha" );

но мне нужно использовать его в реальном коде в качестве аргумента функции, как в

foo( CompileTimeHash( "aha" ) ); // foo is NOT constexpr

По определенной причине я не могу использовать длинную версию

constexpr auto hash = CompileTimeHash( "aha" );
foo( hash );

Компилятор (VC ++) не будет хэшировать время компиляции в коротком (первом) случае. Есть ли способ добиться этого?

РЕДАКТИРОВАТЬ : пример, охватывающий 3 случая, теперь находится здесь: https://godbolt.org/z/JGAyuE Только gcc делает это во всех 3 случаях

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Если я правильно понимаю, ваши CompileTimeHash() возвращают int.

Так что насчет

foo( sizeof(char[CompileTimeHash( "aha" )]) );

Если CompileTimeHash() возвращает только положительные числа, очевидно.

Если CompileTimeHash() возвращает неотрицательные числа (положительные числа или ноль), вы можете решить проблему с нулем (неприемлемо как размер для массива в стиле C), сложив (внутри) и вычитая (снаружи) 1

Я имею в виду

foo( sizeof(char[CompileTimeHash( "aha" )+1])-1u );
0 голосов
/ 24 августа 2018

Что ж, правило as-if всегда позволяет выполнять оценку во время выполнения.Каким бы безумным (и безумно сложным) это ни было.

Лучший способ заставить ваш компилятор сделать это во время компиляции, передать его через аргумент шаблона:

Немного настройки:

template <auto x>
using make_integral_constant = std::integral_constant<decltype(x), x>;

template <auto x>
inline constexpr auto want_static = make_integral_constant<x>::value;

И используйте это как:

foo( want_static<CompileTimeHash( "aha" )> );

Это работает даже без оптимизации , потому что если вы не используете интерпретатор, выполнение этого во время выполнения вместо этого слишкомСложно сделать без веской причины.


Назначение переменной constexpr также должно работать.Но на самом деле проще не оценивать во время компиляции, поэтому без оптимизации, которая все равно происходит .

foo( []{ constexpr auto r = CompileTimeHash( "aha" ); return r; }() );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...