Случайное выражение не постоянное
Я получаю ошибку "case expression not constant" в инструкции switch. Однако заголовок предоставляет определение для используемых констант, а конструктор обеспечивает инициализацию для них в своем списке инициализации.
Кроме того, когда я нажимаю на "проблемные" операторы, он идентифицирует их как константы.
const int ThisClass::EXAMPLE_CONSTANT
error expression must have a constant value
Это кажется мне немного контр-интуитивным. Я сделал некоторые исследования и нашел аналогичную проблему, что кто-то еще. Им сказали, что все константы на самом деле должны быть инициализированы в "главном" и что это ограничение языка. Это действительно так? Это кажется маловероятным.
Ответы
Ответ 1
Операторы case
требуют целочисленного значения, которое должно быть известно во время компиляции, что и подразумевается под константой здесь. Но члены класса const
не очень постоянны в этом смысле. Они просто доступны только для чтения.
Вместо полей вы можете использовать enum
:
class ThisClass
{
public:
enum Constants
{
EXAMPLE_CONSTANT = 10,
ANOTHER_CONSTANT = 20
};
};
А затем вы можете написать
switch(c)
{
case ThisClass::EXAMPLE_CONSTANT:
//code
break;
case ThisClass::ANOTHER_CONSTANT:
//code
break;
};
Ответ 2
Вам нужна "реальная" константа целочисленного времени компиляции. const
в С++ означает только для чтения, а переменная const может
инициализироваться так же, как int y = 0; const int x = y;
, делая x
только для чтения значение y
, имеющееся только для чтения, во время инициализации.
С помощью современного компилятора вы можете использовать enum
или constexpr
для хранения (интегральных) элементов времени компиляции:
class Foo {
public:
static constexpr int x = 0;
enum { y = 1 };
};
int main () {
switch (0) {
case Foo::x: ;
case Foo::y: ;
}
}
Ответ 3
Константы, используемые в методах case, должны быть неотъемлемыми постоянными выражениями. Интегральное константное выражение должно удовлетворять гораздо более строгим требованиям, чем просто интегральный объект, объявленный как const
.
Нестатический член класса не может использоваться в интегральном постоянном выражении, поэтому то, что вы пытаетесь сделать, не будет компилироваться. Например, статический член класса может использоваться в интегральном постоянном выражении, если его инициализатор является "видимым" в точке использования.
Ответ 4
Это немного беспорядок. В С++ const
можно использовать для нескольких вещей, таких как объявление реальных констант и объявление переменных только для чтения.
Если вы заявляете:
const int x = 0;
В глобальном, пространстве имен или локальной области это константа. Вы можете использовать его там, где требуются постоянные выражения (например, метки меток или размеры массива). Однако в классе или в качестве параметра функции это просто переменная только для чтения.
Кроме того, если вы объявляете в области класса:
static const int x = 0;
Это также константа.
Ответ 5
std::map
+ С++ 11 обходной путь lambdas
Этот метод допускает не константы, должен дать нам O(1)
amortized Каков наилучший способ использования HashMap в С++?:
#include <ctime>
#include <functional>
#include <unordered_map>
#include <iostream>
int main() {
int result;
int key0 = std::time(NULL) % 3;
int key1 = (key0 + 1) % 3;
int key2 = (key0 + 2) % 3;
std::unordered_map<int,std::function<void()>> m{
{key0, [&](){ result = 0; }},
{key1, [&](){ result = 1; }},
{key2, [&](){ result = 2; }},
};
m[key0]();
std::cout << key0 << " " << result << std::endl;
m[key1]();
std::cout << key1 << " " << result << std::endl;
m[key2]();
std::cout << key2 << " " << result << std::endl;
}
Возможный выход:
1 0
2 1
0 2
Для использования внутри класса не забудьте создать карту статически, как показано на рисунке: Почему оператор switch не может применяться к строкам?