什么时候定义基本数据类型才有意义? 一个公司的内部C++编码标准文档指出,即使对于int、char等基本数据类型,也应该定义自己的Type Debug,例如“TyPulfItint”。代码的可移植性优势证明了这一点。 然而,对于何时(在何种类型的项目中)它真的有意义,是否有一般性的考虑/建议? 提前感谢。

什么时候定义基本数据类型才有意义? 一个公司的内部C++编码标准文档指出,即使对于int、char等基本数据类型,也应该定义自己的Type Debug,例如“TyPulfItint”。代码的可移植性优势证明了这一点。 然而,对于何时(在何种类型的项目中)它真的有意义,是否有一般性的考虑/建议? 提前感谢。,c++,coding-style,C++,Coding Style,Typedefinginttoint几乎没有任何优势(它不提供语义上的好处,并导致在其他平台上出现类似typedef long int的荒谬行为以保持兼容) 然而,typedefingint到例如int32_t(以及long到int64_t等)确实提供了一个优势,因为您现在可以自由地以自文档的方式选择具有相关宽度的数据类型,并且它是可移植的(只需在不同的平台上切换typedefs) 事实上,大多数编译器都提供了一个stdint.h,它已经包含了所有这些定义。这取决于具体情况。你举的例子是: ty

Typedefing
int
to
int
几乎没有任何优势(它不提供语义上的好处,并导致在其他平台上出现类似
typedef long int
的荒谬行为以保持兼容)

然而,typedefing
int
到例如
int32_t
(以及
long
int64_t
等)确实提供了一个优势,因为您现在可以自由地以自文档的方式选择具有相关宽度的数据类型,并且它是可移植的(只需在不同的平台上切换typedefs)


事实上,大多数编译器都提供了一个stdint.h,它已经包含了所有这些定义。

这取决于具体情况。你举的例子是:

typedef int Int;
他简直是哑巴。这有点像定义一个常数:

const int five = 5;
正如变量
five
成为不同数字的可能性为零一样,typedef
Int
也只能引用基元类型
Int

OTOH,像这样的类型定义:

typedef unsigned char byte;
typedef unsigned long long uint64;
使手指的使用更加方便(尽管它没有便携性的好处),如下所示:

typedef unsigned char byte;
typedef unsigned long long uint64;
更容易输入,也更便于携带,因为在Windows上,您可以编写以下内容(我认为):

垃圾

“可移植性”是没有意义的,因为
int
始终是
int
。如果他们认为需要32位的整数类型,那么typedef应该是
typedef int int32,因为您正在命名一个实不变量,并且可以通过预处理器等确保该不变量保持不变


但这当然是浪费时间,因为您可以在C++0x中或通过扩展使用
,也可以使用Boost的实现。

Typedefs可以帮助描述数据类型的语义。例如,如果您
typedef float distance\u t
,您让开发人员了解如何解释
距离的值。例如,您可能会说这些值可能永远不会为负。什么是-1.23公里?在这种情况下,负距离可能没有意义

当然,typedefs不会以任何方式约束值的域。这只是一种使代码(至少应该)可读并传递额外信息的方法

您的工作场所似乎提到的可移植性问题是,无论使用何种编译器,您都希望确保特定数据类型的大小始终相同。比如说

#ifdef TURBO_C_COMPILER
typedef long int32;
#elsif MSVC_32_BIT_COMPILER
typedef int int32;
#elsif
...
#endif

我想,主要原因是代码的可移植性。例如,一旦您假设在程序中使用32位整数类型,您就需要了解另一方的平台int也是32位长。标题中的Typedef可以帮助您将代码的更改本地化到一个地方。

Typedef int
是一个非常糟糕的想法。。。人们会想知道他们是否在看C++,很难打字,视觉上分散注意力,而且它的唯一模糊的合理化是有缺陷的,但是让我们把它明确地放出来,这样我们就可以把它敲下来:

如果有一天说一个32位的应用程序被移植到64位,并且有很多愚蠢的代码只适用于32位整数,那么至少typedef可以更改为将整数保持在32位

批评:如果系统中的代码写得太糟糕(即没有使用cstdint中的显式32位类型),那么很可能会有代码的其他部分,现在需要使用64位整数,而这些整数将通过typedef卡在32位上。使用Int与库/系统API交互的代码可能被赋予Int,从而导致截断句柄,直到它们恰好超出32位范围等。。无论如何,代码在可信之前都需要彻底的重新检查。这种理由在人们的脑海中游荡只会阻止他们在实际有用的地方使用显式大小的类型(“你这样做是为了什么?”“可移植性?”“但Int是为了可移植性,就用它吧”)

也就是说,编码规则可能是为了鼓励对逻辑上不同类型的事物进行typedef,例如温度、价格、速度、距离等。。在这种情况下,typedef可能有点用处,因为它们允许以一种简单的方式重新编译程序,即从
浮点
精度升级到
双精度
,从实类型降级到整数类型,或者用一些特殊行为替换用户定义的类型。对于容器来说,它也非常方便,因此如果容器发生变化,那么工作量和对客户的影响都会减少,尽管这样的更改通常有点痛苦:容器API的设计有点不兼容,因此必须重新检查重要部分,而不是编译,但不工作,或者默默地执行比以前更糟糕的操作

但是必须记住,
typedef
只是实际底层类型的“别名”,实际上并不创建新的不同类型,因此人们可以传递相同类型的任何值,而不会收到任何类型不匹配的编译器警告。可以使用以下模板解决此问题:

template <typename T, int N>
struct Distinct
{
    Distinct(const T& t) : t_(t) { }
    operator T&() { return t_; }
    operator const T&() const { return t_; }
    T t_;
};

typedef Distinct<float, 42> Speed;
模板
结构清晰
{
不同的(常数T&T):T_(T){}
运算符T&({return T_;}
运算符常量T&()常量{return T_;}
T!;
};
速度快;
但是,让N的值独一无二是一件痛苦的事。。。您可以使用一个中央
枚举
列出不同的值,或者使用