2011-02-07 35 views
5

o böyle bir şey yapmak mümkün mü: makro bağımlı makro

#define F(x) \ 
    #ifdef DOUBLE \ 
     2*x \ 
    #else \ 
     x \ 
    #endif 

Ben F kullandığınızda, ne şekilde genişler olmadığını makro DOUBLE bağlıdır, böylece

tanımlanır? Sanmıyorum ama umutluyum. GNU açılımları iyidir. bazı yanıtlar yanıt olarak

Düzenleme , gerçekten kod tanımlanmış alır yere bağlı olarak biraz farklıdır bazı kod nesil, yapmak için bu kullanıyorum. Bazı dosyaların dahil edildiği ve ilgili makroların tanımlanması gereken düzen nedeniyle, bu şekilde çevrilmesi biraz faktoring gerektirir. Bunu yapmak zorunda kalabilirim, ama bu köşeden kendimi boyamak zorunda kalmamam çok heyecanlanırdı!

#ifdef DOUBLE 
    #define F(x) (2 * (x)) 
#else 
    #define F(x) (x) 
#endif 

cevap

8

. ya

  • bir makro olarak tanımlanmamış veya

sonra, boş bir belirteç sekansının (örneğin #define DOUBLE) için genişleyen bir makro olarak tanımlanır bu garantisini Özellikle, DOUBLE olduğu

#define F_IMPL_(x)  DOUBLE_IS_DEFINED 
#define F_IMPL_DOUBLE(x) DOUBLE_NOT_DEFINED 

#define F_1(x, m) F_2(x, m) 
#define F_2(x, m) F_IMPL_ ## m (x) 

#define F(x) F_1(x, DOUBLE) 

Kullanım Örneğin: Eğer belirteç değiştirgelidir dolaylı yaklaşımı kullanabilirsiniz

Ön işleme sonra
F(t) 
#define DOUBLE 
F(t) 

Sonuç: DOUBLE (tanımlanmış ise) tek bir bilinen belirteci için genişleyen bir makro olarak tanımlanmış ise bu simge bir parçasını oluşturabilir halinde

DOUBLE_NOT_DEFINED 
DOUBLE_IS_DEFINED 

Bu yaklaşım aynı zamanda, çalışacak bir tanımlayıcı (ör. TRUE veya 1). Bunu işlemek için F_IMPL_ makrosunu F_IMPL_{TOKEN} (ör.veya F_IMPL_1) olarak yeniden adlandırmanız gerekir.

+0

Bu mükemmel. –

+0

Güzel iş. Ancak bunu korumaktan nefret ederim. – AShelly

13

Neden tersi iç içe yapamaz?

#ifdef DOUBLE 
#define F(x) (2*(x)) 
#else 
#define F(x) (x) 
#endif 
3

sayılı yapabileceğiniz en yakın şey bir başlık dosyasında koymak ve bu başlık dosyasını tanımları Eğer değişim umurumda her zaman #include etmektir. Bu bazen "X" deseni olarak adlandırılır, çünkü X tanımını değiştiren bir makro olarak kullanılır.

Örneğin, bu modelin bir ortak kullanım numaralandırma değerleri dize adlarını autogenerate şudur: biz sorunu kısıtlayabilir, bu başarabilirsiniz

// File myenum_values.h 
// NOTE: _no_ header guards so we can include this file multiple times 
X(Apple) 
X(Orange) 
X(banana) 

// File myenum.h 
enum Fruit 
{ 
#define X(x) x, 
#include "myenum_values.h" 
} 

const char *FruitNames[] = 
{ 
#undef X 
#define X(x) #x, 
#include "myenum_values.h" 
}; 

// We now have an array of fruit names without having to define the enum twice