std :: string 또는 char *를 반환하는 전 처리기 지시문을 쓸 수 있습니까?문자열을 얻기위한 전처리 지시문 작성
예를 들어 정수의 경우 :
#define square(x) (x*x)
int main()
{
int x = square(5);
}
나는 동일한 기능을 수행 할 찾고 있어요하지만 스위치의 경우 패턴처럼 문자열. 1을 통과하면 "1"을 반환하고 "2"는 2를 반환해야합니다.
std :: string 또는 char *를 반환하는 전 처리기 지시문을 쓸 수 있습니까?문자열을 얻기위한 전처리 지시문 작성
예를 들어 정수의 경우 :
#define square(x) (x*x)
int main()
{
int x = square(5);
}
나는 동일한 기능을 수행 할 찾고 있어요하지만 스위치의 경우 패턴처럼 문자열. 1을 통과하면 "1"을 반환하고 "2"는 2를 반환해야합니다.
C++의 매크로에서는이 작업을 수행하지 않으려 고합니다. 함수는 괜찮 : 마찬가지로
char const* num_name(int n, char const* default_=0) {
// you could change the default_ to something else if desired
static char const* names[] = {"Zero", "One", "Two", "..."};
if (0 <= n && n < (sizeof names/sizeof *names)) {
return names[n];
}
return default_;
}
int main() {
cout << num_name(42, "Many") << '\n';
char const* name = num_name(35);
if (!name) { // using the null pointer default_ value as I have above
// name not defined, handle however you like
}
return 0;
}
, 평방 함수해야한다고 : 실제로 평방 매우 유용 아니지만
이inline int square(int n) {
return n * n;
}
(방금 직접 곱 것입니다.)
내가 (위의 기능이 괜찮)이 경우에는 권하고 싶지 않다 불구하고 호기심으로,하는 templat 전자 메타 프로그래밍 상응하는 것이 다음 TMP 예에 실패 기본 방법은 당신이 어떤 INT 대신 컴파일 시간 상수를 사용할 필요가있다
template<unsigned N> // could also be int if desired
struct NumName {
static char const* name(char const* default_=0) { return default_; }
};
#define G(NUM,NAME) \
template<> struct NumName<NUM> { \
static char const* name(char const* default_=0) { return NAME; } \
};
G(0,"Zero")
G(1,"One")
G(2,"Two")
G(3,"Three")
// ...
#undef G
하는 것으로. 나는이 추가 단계를 보라
#define STRING_1() "ONE"
#define STRING_2() "TWO"
#define STRING_3() "THREE"
...
#define STRING_A_NUMBER_I(n) STRING_##n()
#define STRING_A_NUMBER(n) STRING_A_NUMBER_I(n)
내가 이것을 본
이 문제는 템플릿 metaprogramming으로 어떤 문제를 해결할 수 있는지 궁금합니다. –
@Chris : 물론, NumName
@Roger - 더 큰 숫자를 더 작은 수의 조합으로 단순화하는 깔끔한 트릭을 수행 할 수 있는지 궁금합니다. 템플릿 시스템은 범위를 허용하지 않습니다 (예 :'template <> struct NumName <21-29>') 그래서 그것은 매우 유용하게 끝나지 않습니다. –
#define
전 처리기 지시문은 소스 코드의 문자열을 대체합니다. 당신이 원하는 case...when
구조는 여전히 사소한되지 않습니다 :
#define x(i) ((i)==1?"One":((i)==2?"Two":"Many"))
는 시작이 될 수도 -
#define x(i) xsof[max(0, min((i)-1, (sizeof xsof/sizeof xsof[0] - 1)))]
더 합리적이고 더 나은 성능 보인다
static char* xsof[] = ["One", "Two", "Many"];
및
좋아하지만 정의 뭔가. : Chris Lutz의 제안에 따라 두 번째 매크로는 자동으로 xsof
정의로 조정됩니다. 마크 당 1 위를 기록했다.
매크로의 '2'를'(sizeof xsof/sizeof xsof [0] - 1)'로 변경하면 훌륭한 유지 보수가 가능한 솔루션을 얻을 수 있습니다. –
주어진 매크로의'(i)'는 실제로'(i) - 1'이 아니어야합니까? –
@Michael, 아 그래, 한 번 편집에서 고치기를 원한다고 말했다. @ 크리스, 좋은 생각, 그것을 통합 편집. –
정수를 문자열로 변환 할 수 없으므로 각 값을 열거하지 않는 한 1 -> "1", 2 -> "2"등이됩니다.
당신은 C 프리 프로세서와 문자열로 인수 값을 변환 할 수 있습니다
#define STRINGIZER(x) #x
#define EVALUATOR(x) STRINGIZER(x)
#define NAME(x) EVALUATOR(x)
NAME(123) // "123"
#define N 123
#define M 234
NAME(N+M) // "123+234"
도 SO 1489932를 참조하십시오.
...이, 당신이 1 + 2를 통과하면 STRING_A_NUMBER_I에 전달하기 전에,이 3으로 변환됩니다, 그래서 확인 n이 평가하는 것입니다 조금은 피하는 것, 누군가 정교 할 수 있니?
정상적인 기능이 아닌 이유는 무엇입니까? –
마틴 (Martin)이 말했듯이'square()'매크로 예제는 매크로를 잘못 작성하는 것이 쉬운 이유 중 하나를 보여줍니다. 'square()'매크로는'square (1 + 4)'와 같은 문제를 피하기 위해'#define square (x) (x) * (x))와 비슷해야한다. 그 수정, 부작용이 인수와 잘못된 동작을 방지하기가 어렵습니다. 함수는 이러한 문제를 피하고 성능에 눈에 띄는 영향을 미치지 않을 것입니다 (특히 인라인으로 만들 수있는 경우). –
간단한 매크로 나 인라인 함수를 사용하면 컴파일 타임이나 런타임에만 성능이 향상됩니까? – cpx