Почему std :: get <T>, где T - результат вызова функции constexpr, терпит неудачу? - PullRequest
0 голосов
/ 01 ноября 2019

Я спрашиваю о том, как на самом деле работает этот код:

std::variant<int, std::string> is;
constexpr int i = 0;
std::cout << std::get<i>(is);

И теперь, если я напишу следующий код, он не будет работать:

std::variant<int, std::string> is;
std::cout << std::get<is.index()>(is);

В документации https://en.cppreference.com/w/cpp/utility/variant/index я обнаружил, что тип возвращаемого индекса constexpr. Может ли кто-нибудь помочь мне с этим?

Обновление

Теперь, используя std :: string_view вместо std :: string, который тоже может быть constexpr, а is также constexpr. Оно работает. Спасибо

Ответы [ 2 ]

2 голосов
/ 01 ноября 2019

Метод constexpr может возвращать значение constexpr, если вызывается из значения constexpr.

Таким образом, вы должны определить is как constexpr

 constexpr std::variant<int, std::string> is;

К сожалению, std::variant нельзя объявить constexpr, если if не является литеральным типом, поэтому, когда один из его типов, например std::string, не является литеральным.

Но работает,пример

 constexpr std::variant<int, long> is;
0 голосов
/ 01 ноября 2019

Значения параметров шаблона должны быть известны во время компиляции.

std::variant<int, std::string> is;
constexpr int i = 0;
std::cout << std::get<i>(is);

Это работает, потому что значение i объявлено с constexpr и, таким образом, известно во время компиляции, поэтому выэффективный вызов std::get<0>(is).

std::variant<int, std::string> is;
std::cout << std::get<is.index()>(is);

Это не удается, поскольку is не объявлено с constexpr и, следовательно, значение, которое возвращает is.index(), не может быть известно до времени выполнения, поэтому его нельзя использоватьв параметре шаблона.

...