2

문제는 다음 코드에서 설명합니다.C++ 제네릭 프로그래밍의 미묘한 차이

#include <iostream> 

#define X 4 

int main() 
{ 

    std::cout << "should be 4: " << X << std::endl; 
#define Y X + 4 
    std::cout << "should be 8: " << Y << std::endl; 

#undef Y 
#define Y X+0 
#undef X 
#define X Y+1 

    std::cout << "expecting 5: " << X << std::endl; 
} 

오류 :

test2.cc: In function ‘int main()’: 
test2.cc:17: error: ‘X’ was not declared in this scope 

(많은 nginx 모듈 wired up at compile-time을 얼마나 좋아) 나는/코드에서 프로그램을 확대하고 모방 수준을 구축을 위해 노력하고 패턴입니다. 확장 가능한 컴파일 시간 구조를 구축해야합니다.이 구조는 내 플러그인에 #include을 추가하면 boostable-mpl-vector에 고유 한 이름이 추가됩니다. 따라서 X이 고유 한 끝 이름 인 경우 X_0, X_1, X_2는 벡터에 적용된 벡터 mpl-push_back이있는 과정에서 생성되는 이름입니다. 부스트의

내가 알고 추상성 :: 전처리 키,하지만 난 결국 될 시스템의 일부 프로토 타입거야 나는, 그냥 아직 연구에 시간을 커밋 컴파일을 시간을 원하지 않는 모듈화.

그래서, 나중에 참조 할 수 있도록,

  1. 이유는 위의 오류는 무엇입니까?
  2. 올바른 원시 프로세서 패턴이 어떻게 생겼을 까?
  3. 올바른 부스트 - 전 처리기 라이브러리 패턴은 어떻게 생겼습니까?
+1

당신은 C++ 컴파일러가 컴파일하려고하는 것을보기 위해 전처리기를 통해 이것을 실행 해 보았습니까? –

답변

5

이 있습니다 : 당신이 오류가 발생하는 이유

int main() 
{ 

    std::cout << "should be 4: " << 4 << std::endl; 

    std::cout << "should be 8: " << 4 + 4 << std::endl; 






    std::cout << "expecting 5: " << X+0 +1 << std::endl; 
} 

그래서 당신이 볼 수 있습니다.

Y는 X + 0으로 정의되며, X는 Y + 1과 같이 정의된다

4

한 돌로 두 마리를 죽이고 네임 스페이스를 사용하지 않는 이유는 무엇입니까?

// a.hpp: 

namespace a { 
    const int module_id = 0; 

    class module_a : extension_module<module_id> { … }; 
} 

#undef last_module 
#define last_module a 

// b.hpp: 

namespace b { 
    const int last = last_module::module_id + 1; 

    class module_b : extension_module<module_id> { … }; 
} 

#undef last_module 
#define last_module b 

이는 "영리"방법 이하 및 ID의의 흔적을 남긴다.

그러나 모듈은 ODR이 작동 할 때마다 동일한 순서로 포함되어야합니다.

나는 새를 죽이는 것을지지하지 않습니다. g ++ -E 컴파일

+0

나는 지난 20 분 동안 당신의 대답을 꼼짝 않고 바라 보았습니다. 유레카가 방금 맞았습니다. const 정수 + 네임 스페이스를 통한 템플릿 전문화는 실제로 내 문제에 대한 깨끗하고 우아한 솔루션이며, MPL 또는 전 처리기를 향상시킬 필요가 없습니다.그것들은 C++에서 너무 많은 병렬 수준의 간접 지정입니다. D. 나는 그것이 질문에 가장 관련이 있기 때문에'GCC -E' 대답을 받아 들일 것이다. 그러나 당신의 대답은 전체적인 가치가 더 높고 채택 할 해결책이다. –

+0

@Hassan : Lol, 나는 당신이 이미 그렇게했다고 가정했기 때문에'gcc -E' 결과에 대해서는 언급하지 않았고 단지 해결책을 원했습니다 : vP – Potatoswatter

2

코드 샘플의 문제는 X와 Y 매크로에서 순환 종속성을 가지고있다. 따라서 매크로가 확장되면 (X를 사용하는 지점에서 발생) 문제가 발생합니다.

는 ADD :

그것은 그 행동을 보인다는 이것이다 : 당신이 X 확장으로 X + 0 + 1을 볼 수 있도록 전처리 네임 스페이스에 정의되지 않은 그 정의의 이름 X 내부 매크로 X을 확장 할 때.