2010-05-25 28 views
6

是否可以在预处理器指令中使用非类型常量模板参数?下面是我的想法:在预处理器指令中使用模板参数吗?

template <int DING> 
struct Foo 
{ 
    enum { DOO = DING }; 
}; 

template <typename T> 
struct Blah 
{ 
    void DoIt() 
    { 
     #if (T::DOO & 0x010) 

     // some code here 

     #endif 
    } 
}; 

当我尝试这样的东西,如Blah<Foo<0xFFFF>>,VC++ 2010抱怨一些关于该行括号不匹配,我们正在尝试使用#if。我猜测预处理器并不知道任何关于模板的事情,而这种事情不在其领域内。说啥?

+0

只是一个点要注意的:'胡说>'不会在当前的C解析++,你需要'>'s之间的空间。 'Blah >'。 – KitsuneYMG 2010-05-25 12:30:59

+0

实际上,在VC++ 2010中它编译! :)他们在VC++ 2010中部分实现了C++ 0x。 – Raj 2010-05-25 13:21:58

回答

11

不,这是不可能的。预处理器非常笨,并且它不知道程序的结构。如果T::Doo未在预处理器中定义(并且由于::而不能定义),它不能评估该表达式并且会失败。

但是,你可以依靠编译器做聪明的事情你:

 if (T::Doo & 0x010) { 
      // some code here 
     } 

常量表达式和枯枝甚至在较低的优化设置优化掉,所以你可以放心地做到这一点没有任何运行时开销。

+0

如果'Doo'不存在于'T'中,这不会无法编译吗? – 2010-05-25 12:40:51

+0

谢谢。我也这么想。然而使用编译器对我来说并不理想,因为'T'中有哪些成员可用,取决于'T :: DOO'中设置了哪些位。我确信我正在接近这个错误的方式。我会找出其他的东西。但只是好奇我们可以用预处理器走多远。 另一种选择可能是查看是否可以使用模板元编程技巧。 – Raj 2010-05-25 13:28:54

+0

他们可能会。如果你用你想要完成的细节开启一个新问题,我们可以看看。 – Thomas 2010-05-25 13:50:10

2

什么会员T中可用取决于其位在T::DOO

设置这听起来好像是T::DOO表现得像一个子类标识符。所以我认为你的Foo和相关的类应该是保证定义DOO的类的子类。

关键是:为什么你必须使用位域?

+0

答案是有点涉及,但你完全正确。我正在使用这个API(DirectX),它允许一定的灵活性来指定如何格式化作为输入传递给其某个方法的特定结构的内容。关于如何进行结构设置的信息通过位域传递。在我的应用程序中,我有2个抽象 - 第一个是一个模板类,用于生成此结构的实例的集合,并且该结构本身作为模板参数传递,另一个消耗此集合。 评论继续。低于 – Raj 2010-05-25 16:07:47

+0

我想在使用该结构的特定成员的使用者类中编写一些条件代码,方法是检查哪些位在位字段中设置。唷!我不知道这有多合理!由于源类的各种模板实例与结构的不同变体映射,所涉及的代码必须进行条件编译 - 因此试图查看是否可以使用预处理器。 – Raj 2010-05-25 16:08:32

1

不确定这是否适用于您的情况,但可以使用模板类隔离不同的案例。例如:(使用你的代码的修改版本从上面)

template <typename T, int N> 
struct Blah 
{ 
    void DoIt() 
    { 
     // normal DoIt() code 
    } 
}; 

template <typename T> 
struct Blah<T,5> 
{ 
    void DoIt() 
    { 
     // special DoIt() code for only when N==5 
    } 
};