这段C++代码试图实现什么目标?

3

我正在学习DTMF代码,网址是http://sourceforge.net/projects/dtmf/。我遇到了一些C++代码,但不太理解:

template<int, int, int, int> class Types;
template <> class Types<5, 4, 2, 1>
{
public:
        typedef long int Int40;
        typedef unsigned long int Uint40;
        typedef int Int32;
        typedef unsigned int Uint32;
        typedef short int Int16;
        typedef unsigned short int Uint16;
        typedef char Int8;
        typedef unsigned char Uint8;
};
template <> class Types<8, 4, 2, 1>
{
public:
        typedef long int Int64;
        typedef unsigned long int Uint64;
        typedef int Int32;
        typedef unsigned int Uint32;
        typedef short int Int16;
        typedef unsigned short int Uint16;
        typedef char Int8;
        typedef unsigned char Uint8;
};
template <> class Types<4, 4, 2, 1>
{
public:
        typedef int Int32;
        typedef unsigned int Uint32;
        typedef short int Int16;
        typedef unsigned short int Uint16;
        typedef char Int8;
        typedef unsigned char Uint8;
};

// For 16bit chars
template <> class Types<2, 1, 1, 1>
{
public:
        typedef long int Int32;
        typedef unsigned long int Uint32;
        typedef short int Int16;
        typedef unsigned short int Uint16;
};

typedef Types<sizeof(long int), sizeof(int), sizeof(short int), sizeof(char)>::Int32     INT32;
typedef Types<sizeof(long int), sizeof(int), sizeof(short int), sizeof(char)>::Uint32    UINT32;
typedef Types<sizeof(long int), sizeof(int), sizeof(short int), sizeof(char)>::Int16     INT16;
typedef Types<sizeof(long int), sizeof(int), sizeof(short int), sizeof(char)>::Uint16    UINT16;

从那里开始,它们就像普通的原始类型一样使用:

static const INT16 tempCoeff[8];

我的直觉告诉我,这些东西可以在不同平台之间实现一定的可移植性。我是对的,还是还有其他方面?


3
是的,跨平台标准化字节大小。 - im so confused
1
看起来他在以特别复杂的方式处理不同的架构模型,例如8、4、2、1是8字节长、4字节整数、2字节短整数和1字节字符。我不确定为什么你不直接使用<stdint.h>呢? - Paul R
1
@Paul R 我有一个奇怪的记忆,即 MS 编译器不提供 stdint.h - Mark B
1
五个字节的long?我想知道那是什么样的机器。 - Robᵩ
1
@Rob:可能是一款DSP(我猜测是TI的)。 - Paul R
显示剩余2条评论
3个回答

5

看起来他们正在重新发明 stdint.h(我认为在某些/许多版本的MS编译器中不受支持),通过基于对 sizeof 的调用提供某些特定大小整数类型的一种相当可移植的机制。请注意,接受 sizeof(char) 的第四个模板参数完全无用,因为sizeof(char)始终为1。


是的,微软不关心 C 语言,并且从未实现过 C99 标准。在 C++ 中,只有在 C++11 中采用了 stdint,而微软是最后一个实现它的(Clang 已经支持得几乎完整,gcc 紧随其后,VisualC++ 只具备其中大约一半的功能)。 - Jan Hudec
此外,许多系统只有古老的编译器。各种嵌入式系统通常每隔几年才会更新编译器。 - Jan Hudec
+1 对于 sizeof(char)。当有人希望提供一个“框架”并在基础知识上犯错时,总是让我感到担忧...(而且使用有符号类型作为 sizeof 的结果也不是特别美观)。 - Matthieu M.

2

我们来看看是否可以想出一个更加明智的方法(需要正确定义平台的CHAR_BIT):

namespace portable_inttypes
{
    template<typename Tchain, typename T, typename Tun, size_t Tsize = sizeof (T) * CHAR_BIT, bool atleast64 = Tsize >= 64>
    struct autodef_helper64 : Tchain {};

    template<typename Tchain, typename T, typename Tun, size_t Tsize>
    struct autodef_helper64<Tchain, T, Tun, Tsize, true> : Tchain
    {
        typedef T int_least64_t;
        typedef Tun uint_least64_t;
    };

    template<typename Tchain, typename T, typename Tun>
    struct autodef_helper64<Tchain, T, Tun, 64, true> : Tchain
    {
        typedef T int64_t, int_least64_t;
        typedef Tun uint64_t, uint_least64_t;
    };

    template<typename Tchain, typename T, typename Tun, size_t Tsize = sizeof (T) * CHAR_BIT, bool atleast32 = Tsize >= 32>
    struct autodef_helper32 : autodef_helper64<Tchain, T, Tun> {};

    template<typename Tchain, typename T, typename Tun, size_t Tsize>
    struct autodef_helper32<Tchain, T, Tun, Tsize, true> : autodef_helper64<Tchain, T, Tun>
    {
        typedef T int_least32_t;
        typedef Tun uint_least32_t;
    };

    template<typename Tchain, typename T, typename Tun>
    struct autodef_helper32<Tchain, T, Tun, 32, true> : autodef_helper64<Tchain, T, Tun>
    {
        typedef T int32_t, int_least32_t;
        typedef Tun uint32_t, uint_least32_t;
    };

    template<typename Tchain, typename T, typename Tun, size_t Tsize = sizeof (T) * CHAR_BIT, bool atleast32 = Tsize >= 16>
    struct autodef_helper16 : autodef_helper32<Tchain, T, Tun> {};

    template<typename Tchain, typename T, typename Tun, size_t Tsize>
    struct autodef_helper16<Tchain, T, Tun, Tsize, true> : autodef_helper32<Tchain, T, Tun>
    {
        typedef T int_least16_t;
        typedef Tun uint_least16_t;
    };

    template<typename Tchain, typename T, typename Tun>
    struct autodef_helper16<Tchain, T, Tun, 16, true> : autodef_helper32<Tchain, T, Tun>
    {
        typedef T int16_t, int_least16_t;
        typedef Tun uint16_t, uint_least16_t;
    };

    template<typename Tchain, typename T, typename Tun, size_t Tsize = sizeof (T) * CHAR_BIT, bool atleast8 = Tsize >= 8>
    struct autodef_helper8 : autodef_helper16<Tchain, T, Tun> {};

    template<typename Tchain, typename T, typename Tun, size_t Tsize>
    struct autodef_helper8<Tchain, T, Tun, Tsize, true> : autodef_helper16<Tchain, T, Tun>
    {
        typedef T int_least8_t;
        typedef Tun uint_least8_t;
    };

    template<typename Tchain, typename T, typename Tun>
    struct autodef_helper8<Tchain, T, Tun, 8, true> : autodef_helper16<Tchain, T, Tun>
    {
        typedef T int8_t, int_least8_t;
        typedef Tun uint8_t, uint_least8_t;
    };

    struct autodef_base {};
    typedef autodef_helper8<autodef_base, long long, unsigned long long> autodef_longlong;
    typedef autodef_helper8<autodef_longlong, long, unsigned long> autodef_long;
    typedef autodef_helper8<autodef_long, int, unsigned> autodef_int;
    typedef autodef_helper8<autodef_int, short, unsigned short> autodef_short;
    typedef autodef_helper8<autodef_short, signed char, unsigned char> autodef_char;
}

typedef portable_inttypes::autodef_char inttypes;

int main(void)
{
    return sizeof(inttypes::uint32_t);
}

1

这段代码计算了不同基本标量类型的大小,并根据其定义了一些类型。

因此,它确实用于跨平台兼容性。但为什么要以那种方式使用,超出了我的理解范围。


有更好的方法吗? - mpenkov
这通常是通过一堆宏来完成的(这就是 stdint.h 的作用)。这段代码的问题在于它处理了四种特定类型的架构,如果大小不匹配其中一种模式,则会出现可悲的错误。 - slaphappy
很高兴听到这不是处理这类问题的标准方式。我也在考虑宏。 - mpenkov
@misha:这个标准相当新。微软从未费心实现引入此功能的C99,而C++11也是全新的;在许多情况下,您仍然需要支持基于C89的C++03,这是一个不错的选择。 - Jan Hudec
@misha:看一下我的答案(未经测试),可以根据平台自动定义特定大小的类型。 - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接