做在线OJ的时候往往不能看到程序的运行输出,但我们仍然可以从编译器提供的错误信息中得到不少有价值的信息。比如说编译器的类型、版本以及使用的库等等。同样,当我们没有本地编译器的时候,也可以利用这些技巧+在线编译器(比如
http://www.dinkumware.com/exam/default.aspx)获得我们感兴趣的信息(比如结构对齐信息,复杂对象类型等等)
1、输出宏的内容
基本的思想就是利用C++中string literal不能作为模版参数的特性。通常编译器会将string literal的内容也一并输出。下面的code snippet显示了如何输出GCC的版本号。宏F0和F1用于将宏展开并转换成对应的字符串
template<const char *>
class A
{
};
#define F0(x) #x
#define F1(x) F0(x)
#define V1 F1(__GNUC__)
#define V2 F1(__GNUC_MINOR__)
#define V3 F1(__GNUC_PATCHLEVEL__)
int main()
{
A<V1> a1;
A<V2> a2;
A<V3> a3;
}
2、输出常数的数值
同样,目前的C++标准不支持浮点数作为模版参数。通常编译器会输出浮点数的值以供参照,所以可以利用这个特性输出浮点数的值。不过VC有个bug,当使用浮点数作为模版参数时,会自动隐式转换成int,所以不会报错( https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=296008)。
下面展示另一种用于输出整型数值的Trick。
struct N
{
char a;
int b;
char i;
};
template<int N>
class A
{
private:
A();
};
int main()
{
A<sizeof(N)> a;
}
3、输出变量的类型
目前的标准还不支持decltype,所以为了查看复杂对象的类型,可以使用下面的方法。
#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;
struct Dummy {};
void Fun(const Dummy &);
int main()
{
Fun(_1+(_1*_2)/_1);
}
1、输出宏的内容
基本的思想就是利用C++中string literal不能作为模版参数的特性。通常编译器会将string literal的内容也一并输出。下面的code snippet显示了如何输出GCC的版本号。宏F0和F1用于将宏展开并转换成对应的字符串
template<const char *>
class A
{
};
#define F0(x) #x
#define F1(x) F0(x)
#define V1 F1(__GNUC__)
#define V2 F1(__GNUC_MINOR__)
#define V3 F1(__GNUC_PATCHLEVEL__)
int main()
{
A<V1> a1;
A<V2> a2;
A<V3> a3;
}
2、输出常数的数值
同样,目前的C++标准不支持浮点数作为模版参数。通常编译器会输出浮点数的值以供参照,所以可以利用这个特性输出浮点数的值。不过VC有个bug,当使用浮点数作为模版参数时,会自动隐式转换成int,所以不会报错( https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=296008)。
下面展示另一种用于输出整型数值的Trick。
struct N
{
char a;
int b;
char i;
};
template<int N>
class A
{
private:
A();
};
int main()
{
A<sizeof(N)> a;
}
3、输出变量的类型
目前的标准还不支持decltype,所以为了查看复杂对象的类型,可以使用下面的方法。
#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;
struct Dummy {};
void Fun(const Dummy &);
int main()
{
Fun(_1+(_1*_2)/_1);
}