从技术上讲是可能的,只是非常丑陋。以下是一个示例,它生成一个无符号整数的字符串字面量。它尚未创建形如“1 2 3 ... i-1”的字符串,但如果你愿意付出努力,我相信这是可能的。
#include <iostream>
#include <string>
#include <limits>
template <int accum, int base, int exp> struct POWER_CORE : POWER_CORE<accum * base, base, exp - 1>{};
template <int accum, int base>
struct POWER_CORE<accum, base, 0>
{
enum : int { val = accum };
};
template <int base, int exp> struct POWER : POWER_CORE<1, base, exp>{};
template <int depth, unsigned int i> struct NUM_DIGITS_CORE : NUM_DIGITS_CORE<depth + 1, i / 10>{};
template <int depth>
struct NUM_DIGITS_CORE<depth, 0>
{
enum : int { val = depth};
};
template <int i> struct NUM_DIGITS : NUM_DIGITS_CORE<0, i>{};
template <>
struct NUM_DIGITS<0>
{
enum : int { val = 1 };
};
template <int i>
struct DIGIT_TO_CHAR
{
enum : char{ val = i + 48 };
};
template <unsigned int i, int place>
struct DIGIT_AT
{
enum : char{ val = (i / POWER<10, place>::val) % 10 };
};
struct NULL_CHAR
{
enum : char{ val = '\0' };
};
template <unsigned int i, int place>
struct ALT_CHAR : DIGIT_TO_CHAR< DIGIT_AT<i, place>::val >{};
template <unsigned int i, int offset, int numDigits, bool inRange>
struct OFFSET_CHAR_CORE_CHECKED{};
template <unsigned int i, int offset, int numDigits>
struct OFFSET_CHAR_CORE_CHECKED<i, offset, numDigits, false> : NULL_CHAR{};
template <unsigned int i, int offset, int numDigits>
struct OFFSET_CHAR_CORE_CHECKED<i, offset, numDigits, true> : ALT_CHAR<i, (numDigits - offset) - 1 >{};
template <unsigned int i, int offset, int numDigits>
struct OFFSET_CHAR_CORE : OFFSET_CHAR_CORE_CHECKED<i, offset, numDigits, offset < numDigits>{};
template <unsigned int i, int offset>
struct OFFSET_CHAR : OFFSET_CHAR_CORE<i, offset, NUM_DIGITS<i>::val>{};
template <unsigned int i>
struct IntToStr
{
const static char str[];
};
template <unsigned int i>
const char IntToStr<i>::str[] =
{
OFFSET_CHAR<i, 0>::val,
OFFSET_CHAR<i, 1>::val,
OFFSET_CHAR<i, 2>::val,
OFFSET_CHAR<i, 3>::val,
OFFSET_CHAR<i, 4>::val,
OFFSET_CHAR<i, 5>::val,
OFFSET_CHAR<i, 6>::val,
OFFSET_CHAR<i, 7>::val,
OFFSET_CHAR<i, 8>::val,
OFFSET_CHAR<i, 9>::val,
NULL_CHAR::val
};
int _tmain(int argc, _TCHAR* argv[])
{
std::wcout << IntToStr<17>::str << std::endl;
std::wcout << IntToStr<173457>::str << std::endl;
std::wcout << IntToStr< INT_MAX >::str << std::endl;
std::wcout << IntToStr<0>::str << std::endl;
std::wcout << IntToStr<1>::str << std::endl;
std::wcout << IntToStr<-1>::str << std::endl;
return 0;
}
i
是一个预处理器常量,那就很容易了,但是使用模板我想不到解决方法。 - Thomasi
;如果没有结构体,我该如何重写它?我认为template < int i > const char* s = ...;
不会编译。 - Thomas