我的 VC++ 代码在编译期间打印任意数量的编译时间常数的值(例如 sizeof 结构)并继续编译而不会出错:
// cpptest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//#define VALUE_TO_STRING2(x) #x
//#define VALUE_TO_STRING(x) VALUE_TO_STRING2(x)
#define TO_STRING(x) #x
#define FUNC_TEMPLATE_MSG(x,y) "[" x "]""["TO_STRING(y)"]"
template<unsigned int N,unsigned int M>
int printN()
{
#pragma message(FUNC_TEMPLATE_MSG(__FUNCSIG__ ,1))
return 0;
};
struct X {
char a[20];
int b;
};
struct Y {
char a[210];
int b;
};
int _tmain(int argc, _TCHAR* argv[])
{
printN<sizeof(X),__COUNTER__>();
printN<sizeof(Y),__COUNTER__>();
//..as many compile time constants as you like
}
VC++2010 生成的示例输出。目标值是VC++奇怪选择输出为十六进制值的第一个函数模板参数值(示例中为0x18和0xd8)!!
1>------ Build started: Project: cpptest, Configuration: Release Win32 ------
1> cpptest.cpp
1> [int __cdecl printN<0x18,0x0>(void)][1]
1> [int __cdecl printN<0xd8,0x1>(void)][1]
1> Generating code
1> Finished generating code
1> cpptest.vcxproj -> c:\work\cpptest\Release\cpptest.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
这里使用的主要技术是在每个函数模板实例化期间,#pragma message() 指令被调用一次。 Microsoft 特定宏__FUNCSIG__ 可以显示包含函数的签名,从而显示函数模板的每个特定实例中使用的整数值。将COUNTER 作为第二个模板参数是为了确保两个相同值的整数仍然被认为是不同的。 #pragma 指令中的 1 在这里没有用,但可以用作标识符,以防我们有超过 1 个这样的指令并且输出窗口充满杂乱的消息。