Zmienne const w instrukcji switch

Zmienne const w instrukcji switch
Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

Mam takie coś jako zmienna globalna:

Kopiuj
const int jakaszmienna = jakasfunkcja(jakisparametr);

następnie chcę użyć tej stałej w instrukcji switch:

Kopiuj
switch(costam)
{
// ...
case jakaszmienna:
    // ...
    break;
// ...
}

natomiast kompilator wywala błędy:

C2051: Case expression not constant
C2131: Expression did not evaluate to a constant

Nie rozumiem o co chodzi. Przecież jakaszmienna jest stałą.

edytowany 3x, ostatnio: Kamil B
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:2 dni
  • Lokalizacja:Szczecin
1

Musi być stałą znaną w czasie kompilacji. Więc constexpr albo literał.


Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

Niestety moja stała nigdy nie będzie znana w czasie kompilacji. Używam tam funkcji WinAPI: RegisterWindowMessage(L"TaskbarCreated") aby potem użyć tej stałej w procedurze okna. Nie mam pojęcia jak to zrobić

edytowany 1x, ostatnio: Kamil B
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:2 dni
  • Lokalizacja:Szczecin
1

To nie możesz użyć do tego switcha. Co konkretnie chcesz zrobić? cośtam i jakiśparametr są dość mało deskryptywne ;​)


Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

Używam WinAPI do stworzenia okna. W procedurze okna, zauważyłem że musi być switch. Jak zamieniłem na if-y to mi błąd wywalała funkcja CreateWindowEx().

edytowany 1x, ostatnio: Kamil B
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:2 dni
  • Lokalizacja:Szczecin
1

Pokaż więcej kodu, chyba coś robisz bardzo źle.


Althorion
Ta… WinAPI jest mhroczne, ale chyba nie aż tak.
Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

(Uczę się WinAPI)

To mam jako zmienna globalna:

Kopiuj
const UINT WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");

Następnie rejestruję okno:

Kopiuj
LPCWSTR className = L"MainWindow";

WNDCLASSEX mainWnd;
mainWnd.cbSize = sizeof(WNDCLASSEX);
mainWnd.style = 0;
mainWnd.cbClsExtra = 0;
mainWnd.cbWndExtra = 0;
mainWnd.lpfnWndProc = MainWndProc;
mainWnd.hInstance = hInstance;
mainWnd.hCursor = LoadCursor(NULL, IDC_ARROW);
mainWnd.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
mainWnd.hbrBackground = (HBRUSH)COLOR_WINDOW + 1;
mainWnd.lpszMenuName = NULL;
mainWnd.lpszClassName = className;
mainWnd.hIconSm = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));

if (!RegisterClassEx(&mainWnd))
{
	MessageBox(NULL, L"Cannot register window", L"Error", MB_ICONERROR | MB_OK);
	exit(1);
}

Potem tworzę okno:

Kopiuj
MainWndHWND = CreateWindowEx(WS_EX_WINDOWEDGE, className, L"MainWin", WS_POPUP, CW_USEDEFAULT,
	CW_USEDEFAULT, 200, 200, NULL, NULL, hInstance, NULL);

if (MainWndHWND == NULL)
{
	MessageBox(NULL, L"Cannot create window", L"Error", MB_ICONERROR | MB_OK);
	exit(1);
}

A oto MainWndProc():

Kopiuj
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_CREATE:
		break;
	case WM_CLOSE:
		DestroyWindow(MainWndHWND);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_TASKBARCREATED: // C2313, C2051
		break;
	default:
		return DefWindowProc(hWnd, msg, wParam, lParam);
	};
	return 0;
}

W tym mój problem. Gdy w MainWndProc() zamieniłem całego switcha na if-y to mi tworzenie okna nie chodzi.

edytowany 1x, ostatnio: Kamil B
_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:15 dni
2

Użyj:

Kopiuj
typedef LRESULT CALLBACK SomeWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
unordered_map<int,SomeWindowProc*> map;

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 3x, ostatnio: _13th_Dragon
Kamil B
Nie rozumiem
Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

Mógłbyś mi ten kod wytłumaczyć? Nie lubię robić kopiuj-wklej czegoś czego nie rozumiem.

_13th_Dragon
  • Rejestracja:prawie 20 lat
  • Ostatnio:15 dni
1
Kopiuj
#include <unordered_map>
#include <iostream>
using namespace std;

void callById(int i)
{
	typedef void numbers();
	typedef unordered_map<int,numbers*> funmap;
	static const funmap map
	{
		{0,[](){cout<<"zero"<<endl;}},
		{1,[](){cout<<"one"<<endl;}},
		{2,[](){cout<<"two"<<endl;}},
		{3,[](){cout<<"three"<<endl;}},
		{4,[](){cout<<"four"<<endl;}},
		{5,[](){cout<<"five"<<endl;}},
	};
	map.at(i)();
}

int main()
{
	for(int i=0;i<=5;++i) callById(i);
	return 0;
}

Lub może nieco prostsze w zrozumieniu:

Kopiuj
#include <unordered_map>
#include <iostream>
using namespace std;

double operation(double a,char op,double b)
{
	typedef double operationfun(double a,double b);
	static const unordered_map<char,operationfun*> map
	{
		{'+',[](double a,double b){ return a+b; }},
		{'-',[](double a,double b){ return a-b; }},
		{'*',[](double a,double b){ return a*b; }},
		{'/',[](double a,double b){ return a/b; }},
	};
	return map.at(op)(a,b);
}

int main()
{
	cout<<operation(3,'*',4)<<endl;
	return 0;
}

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
Riddle
@Kamil B: Pewnie chciał sobie zadeklarować typ lambdy, ale go nie użył nie wiem czemu
Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

Niestety, tak jak w przypadku if-ów, okno się nie tworzy po przerobieniu procedury okna na std::unordered_map Nie wiem dlaczego w tej procedurze musi być switch. Gdy zamieniłem std::unordered_map z powrotem na switch ale bez tego WM_TASKBARCREATED, wszystko śmiga. Nie mam pojęcia jak mogę dodać obsługę tego felernego komunikatu...

Z tego co zrozumiałem, to moja procedura okna powinna teraz wyglądać tak:

Kopiuj
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	typedef void WndProc();
	static const std::unordered_map<UINT, WndProc*> map
	{
		{WM_CREATE, []() {/* ... */}},
		{WM_DESTROY, []() {/* ... */}},
		// ...
	};
	map.at(msg);
	return 0;
}

Może ja coś źle zrozumiałem.

edytowany 1x, ostatnio: Kamil B
_13th_Dragon
{WM_CREATE, [](HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {/* ... */}},
Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

Teraz program wyrzuca wyjątki (wcześniej zapomniałem dodać map.at()):
screenshot-20201207101351.png
screenshot-20201207101431.png
O czym to świadczy? Jak mogę dodać to std::unordered_map coś takiego jak default w switchu?

edytowany 1x, ostatnio: Kamil B
hzmzp
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 12 godzin
  • Postów:632
0

Twoja 'stała' jest zmienna. Więc powinieneś użyć zmiennej, która powinna być moim zdaniem statyczna.

Kopiuj


class Program {
 private static UINT WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
edytowany 1x, ostatnio: hzmzp
Kamil B
Nie mam klas w swoim programie
Kamil B
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:80
0

Wszystko działa już. Dzięki za pomoc.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.