在某些情况下,库源可用,它通常必须支持可变参数,但实际上这些参数通常是常量。
然后可以通过对常量参数的特殊处理来优化事物(例如,使用静态数组而不是堆分配),但为此有必要首先确定某些东西是否是常量(或者可能定义一些宏,但不太方便)。
所以这是一个有效的实现。
更新:也在这里:http ://codepad.org/ngP7Kt1V
- 它真的是一个有效的 C++ 吗?
- 有没有办法摆脱这些宏?(is_const() 不能是函数,因为函数依赖在数组大小表达式中不起作用;它也不能是模板,因为它也不接受可变参数。)
更新:这是一个更像预期用途的更新。如果不为 0 ,编译器不会为if(N==0)
分支生成任何代码。N
同样,如果我们愿意,我们可以切换到完全不同的数据结构。当然它并不完美,但这就是我发布这个问题的原因。
#include <stdio.h>
struct chkconst {
struct Temp { Temp( int x ) {} };
static char chk2( void* ) { return 0; }
static int chk2( Temp ) { return 0; }
};
#define is_const_0(X) (sizeof(chkconst::chk2(X))<sizeof(int))
#define is_const_0i(X) (sizeof(chkconst::chk2(X))>sizeof(char))
#define is_const(X) is_const_0( (X)^((X)&0x7FFFFFFF) )
#define const_bit(X1,bit) (is_const_0i((X1)&(1<<bit))<<bit)
#define const_nibl(X1,bit) const_bit(X1,bit) | const_bit(X1,(bit+1)) | const_bit(X1,(bit+2)) | const_bit(X1,(bit+3))
#define const_byte(X1,bit) const_nibl(X1,bit) | const_nibl(X1,(bit+4))
#define const_word(X1,bit) const_byte(X1,bit) | const_byte(X1,(bit+8))
#define const_uint(X1) const_word(X1,0) | const_word(X1,16)
#define const_switch_word( X1, X2 ) (is_const(X1) ? const_word(X1,0) : X2)
#define const_switch_uint( X1, X2 ) (is_const(X1) ? const_uint(X1) : X2)
const int X1 = 222;
const int X2 = printf( "" ) + 333;
char Y1[ const_switch_word(X1,256) ];
char Y2[ const_switch_word(X2,256) ];
template< int N >
void test( int N1 ) {
char _buf[N>0?N:1];
char* buf = _buf;
if( N==0 ) {
buf = new char[N1];
}
printf( "%08X %3i %3i\n", buf, N, N1 );
}
#define testwrap(N) test< const_switch_word(N,0) >( N )
int main( void ) {
printf( "%i %i %i\n", X1, is_const(X1), sizeof(Y1) );
printf( "%i %i %i\n", X2, is_const(X2), sizeof(Y2) );
testwrap( X1 );
testwrap( X2 );
}