Программа с двумя определениями одной и той же встроенной функции является неправильно сформированной программой, диагностика не требуется.
Стандарт не устанавливает требований к поведению во время выполнения или компиляции некорректно сформированной программы.
Теперь в C ++ нет «времени компиляции», как вы его себе представляете. В то время как почти каждая реализация C ++ компилирует файлы, связывает их, создает двоичный файл, а затем запускает его, стандартные подсказки C ++ касаются этого факта.
В нем говорится о единицах перевода и о том, что происходит, когда вы объединяете их впрограмма и поведение этой программы во время выполнения.
...
На практике ваш компилятор может строить карту из символа в некоторую внутреннюю структуру. Он компилирует ваш первый файл, а затем во втором файле все еще обращается к этой карте. Новое определение той же встроенной функции? Просто пропустите это.
Во-вторых, ваш код должен создавать выражение постоянной времени компиляции. Но выражение константы времени компиляции не является наблюдаемым свойством в контексте, где вы его использовали, и нет никаких побочных эффектов при выполнении этого при ссылке или даже во время выполнения! И как если бы ничто не мешало этому.
consteval
говорит: «если я запускаю это, и правила, которые допускают, чтобы это было постоянным выражением, нарушались, я должен ошибиться, а не отступить отпостоянное выражение ". Это похоже на «оно должно быть запущено во время компиляции», но это не то же самое.
Чтобы определить, что из этого происходит, попробуйте следующее:
template<auto x>
constexpr std::integral_constant< decltype(x), x > constant = {};
теперь замените ваши строки печати на:
std::cout << constant<get()> << std::endl;
, что делает нецелесообразным откладывать оценку на время выполнения / связывания.
Это будет отличать "умный компилятор откеширование get
"from" компилятор оценивает его позже во время компоновки ", потому что определение того, какой ostream& <<
для вызова, требует создания экземпляра типа constant<get()>
, что, в свою очередь, требует оценки get()
.
Compilersкак правило, не откладывайте разрешение перегрузки на время соединения.