사실 switch에서 문자열을 쓰는 방법은 굉장히 다양하다. map을 써서 enum 형태로 반환되는 함수를 쓸 수도 있을 것이고, 아예 switch 자체를 구현할 수도 있을 것이다.
하지만 오늘 공부한 내용은 좀 활용가치가 높은 것 같아서 기록해두려고 한다.
switch는 특성상 case 다음에 무조건 상수 표현식이 있어야 한다.
그렇기 때문에 일반적인 함수로는 다음과 같은 코드를 만들 수 없다.
unsigned int Hash(const char* s);
//main
switch(Hash(input)){
case Hash("Insert"): {
~~~
}
}
C++11에 constexpr 이라는 키워드가 추가되었다.
constexpr은 변수 또는 함수의 값을 컴파일 시점에 도출하여 상수화 시켜주는 아주 강력한 기능이다.
컴파일 시점에 상수로 처리되기 때문에 switch case 문에서도 상수로 취급된다!
이를 통해 다음과 같은 코드를 만들 수 있다.
constexpr unsigned int Hash(const char* s);
//main
switch(Hash(input)){
case Hash("Insert"): {
~~~
}
}
constexpr을 사용하는 데 있어서 몇가지 제약사항이 있는데 간단하게 정리하고 마무리한다.
다음은 백준의 17347번 Text Editor를 풀이한 코드이다.
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
using ll = long long;
constexpr unsigned int Hash(const char* str){
return str[0] ? static_cast<unsigned int>(str[0]) + 0xEDB8832Full * Hash(str + 1) : 8603;
}
char s[1048577];
crope rp;
int pos = 0;
void execute(const char* operation);
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--){
char operation[10];
cin >> operation;
execute(operation);
}
}
void execute(const char* operation){
switch(Hash(operation)){
case Hash("Move"): {
int k;
cin >> k;
pos = k;
break;
}
case Hash("Insert"): {
int len, tmpPos = pos;
cin >> len;
while(len>0){
cin.getline(s, 1048577);
len -= strlen(s);
rp.insert(pos, s);
pos += strlen(s);
}
pos = tmpPos;
break;
}
case Hash("Delete"): {
int len;
cin >> len;
rp.erase(pos, len);
break;
}
case Hash("Get"): {
int len;
cin >> len;
cout << rp.substr(pos, len) << '\n';
break;
}
case Hash("Prev"): {
pos--;
break;
}
case Hash("Next"): {
pos++;
break;
}
}
}
Microsoft Docs - constexpr(C++)
[C++] switch 문에서 문자열 사용하기 (Feat. constexpr)