正如其他回答所说,这不能通过C预处理器完成。这是C的许多缺点之一,而这些缺点都被C++解决了。这是可以使用模板元编程以非常优雅的方式实现的事情。
要在编译时计算算术表达式:
#include <boost/mpl/arithmetic.hpp>
namespace mpl = boost::mpl;
int main(int argc, char *argv[]) {
const int n = mpl::multiplies<mpl::int_<10>, mpl::int_<50> >::value;
return 0;
}
我在 Boost 邮件列表档案中找到了一个 字符串格式化元函数。这个版本可以将一个整数(例如上面计算的那个)转换为您选择的进制的字符串:
#include <boost/mpl/string.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/push_back.hpp>
namespace mpl = boost::mpl;
struct itoa_ct
{
typedef mpl::vector_c<char
,'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
> radix_t;
template <int Radix, unsigned int Quotient>
struct radix_convert
{
typedef typename mpl::push_back<
typename radix_convert<Radix, Quotient / Radix>::type
, mpl::char_<mpl::at_c<radix_t, Quotient % Radix>::type::value>
>::type type;
};
template <int Radix>
struct radix_convert<Radix, 0>
{
typedef mpl::string<> type;
};
template <int I, int Radix = 10>
struct apply
{
typedef typename radix_convert<
Radix, static_cast<unsigned int>((Radix == 10 && I < 0) ? -I : I)
>::type converted_t;
typedef typename mpl::if_<
mpl::bool_<(Radix == 10 && I < 0)>
, mpl::push_front<converted_t, mpl::char_<'-'> >
, mpl::identity<converted_t>
>::type::type type;
};
};
将这两部分组合起来,你的表达式就变成了:
const char *thestring = mpl::c_str<itoa_ct::apply<mpl::multiplies<mpl::int_<10>, mpl::int_<50> >::value>::type>::value;
......这一切最终在编译时都会变成一个常量字符串"500"而已 :-)