Обойти без внимания constexpr в Visual Studio? - PullRequest
2 голосов
/ 13 июня 2019

У меня есть этот код:

constexpr int log2(const unsigned int x) {
    return x < 4 ? 1 : 1 + log2(x / 2);
}

int main() {
    bitset<log2(2)> foo;
    int bar[log2(8)];

    cout << log2(8) << endl;
}

Это прекрасно работает в gcc: https://ideone.com/KooxoS

Но когда я примеряю , я получаю следующие ошибки:

ошибка C2975: _Bits: недопустимый аргумент шаблона для std::bitset, ожидаемое константное выражение во время компиляции
примечание: см. декларацию _Bits
ошибка C2131: выражение не было константой
примечание: сбой был вызван вызовом неопределенной или не объявленной функции constexpr
примечание: см. использование log2

Очевидно, log2 - это constexpr, поэтому я предполагаю, что это просто ошибка в . Есть ли способ обойти эту ошибку?

Ответы [ 2 ]

5 голосов
/ 13 июня 2019

Похоже, ваш проект включает в себя стандартную функцию std::log2, которую компилятор смешивает с вашей функцией log2.Это может произойти, даже если вы не #include <cmath>, потому что стандартные заголовки могут включать любые другие стандартные заголовки.Это также еще один пример using namespace std; обратной реакции.

Одним из решений является переименование вашей constexpr функции на другое:

#include <bitset>
#include <iostream>

using namespace std;

constexpr int logTwo(const unsigned int x) {
    return x < 4 ? 1 : 1 + logTwo(x / 2);
}

int main() {
    bitset<logTwo(2)> foo;
    int bar[logTwo(8)];

    cout << logTwo(8) << endl;
}

Демо

Редактировать: Кажется, что using namespace std; может быть не связано в этом случае.В любом случае стандартная функция log2 может быть доступна в глобальном пространстве имен.

3 голосов
/ 13 июня 2019

Очевидно, log2 - это constexpr

Функция, являющаяся constexpr, не означает, что ее всегда можно использовать для вычисления значения времени вычислений. Когда x >= 4, вы звоните std::log2, что само по себе не constexpr.

GCC реализует их как расширение. См. Является ли это соответствующим расширением компилятора для обработки функций стандартной библиотеки non-constexpr как constexpr?

...