ライブラリ ソースが利用可能で、一般に変数パラメーターをサポートする必要がある場合がありますが、実際には、これらのパラメーターは一般的に定数です。
次に、定数パラメーターの特別な処理 (たとえば、ヒープ割り当ての代わりに静的配列を使用) によって物事を最適化できる可能性がありますが、そのためには、最初に何かが定数であるかどうかを判断する必要があります (または、いくつかのマクロを定義することもできますが、あまり便利ではありません)。 )。
これが実用的な実装です。
更新: こちらも: http://codepad.org/ngP7Kt1V
- 本当に有効な C++ ですか?
- これらのマクロを取り除く方法はありますか? ( is_const() は、関数の依存関係が配列サイズの式で機能しないため、関数にすることはできません。また、変数パラメーターも受け入れないため、テンプレートにすることもできません。)
更新:これは、意図された使用法に似た更新です。if(N==0)
が 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 );
}