使用 "typedef" 或 "using" 来定义结构 - 哪个最好?
Using "typedef" or "using" to define a structure - which is best?
示例结构:
typedef struct tagExportSettings
{
COLORREF crHeading{};
COLORREF crEvenBack{};
COLORREF crOddBack{};
COLORREF crHighlight{};
COLORREF crDate{};
COLORREF crEvent{};
COLORREF crEmpty{};
COLORREF crNotes{};
} EXPORT_SETTINGS_S;
视觉助手说:
typedef
can be converted to using
declaration.
更改此代码是否有真正的好处?
我在软件中的所有代码都使用 EXPORT_SETTINGS_S
,所以我不想破坏该语法。
更好的是什么都不用。一个类型名称就足够了。选择 tagExportSettings
或 EXPORT_SETTINGS_S
并坚持下去。示例:
struct tagExportSettings
{
// ...
};
But, 1. All my code in the software uses EXPORT_SETTINGS_S
就像我说的,随便选一个名字。如果您使用 EXPORT_SETTINGS_S
,则将 class 命名为 EXPORT_SETTINGS_S
:
struct EXPORT_SETTINGS_S
{
// ...
};
如果某些内容仍然引用 tagExportSettings
,则重构代码以使用规范名称。
但更一般地说,using
优于 typedef
,因为它更具可读性。至少有两个原因:
使用 typedef
语法,不直观哪个是旧名称哪个是新别名:
typedef new_or_old old_or_new; // old_or_new is the new alias
using
通过熟悉的初始化模式很直观:
using intuitively_alias = intuitively_old_name;
typedef
对于复合名称,程序员很难解析语法,因为别名是“交错”的:
// alias for void()
typedef void function();
using function = void();
假设是纯 C++,这取决于您是否使用原始指针。如果不这样做,则只需在不使用 typedef
或 using
.
的情况下以正确的名称定义结构
struct EXPORT_SETTINGS_S
{...
如果您经常使用原始指针并且在 Windows 中,习惯上不仅要定义别名,还要定义指针类型:
typedef struct tagExportSettings
{
...
} EXPORT_SETTINGS_S, *LPEXPORT_SETTINGS_S;
只有当您习惯了 LPXXX
"types" 时,这才重要。如果你是*
人,那就没必要了。
这些都不是 using
的 clear-cut 案例。
如果您使用 C++ 编写,using
会好得多。例如,像这样的模板结构:
template <typename Tp>
struct WrapData
{
const bool has_value = !std::is_void<Tp>::value;
typename std::conditional<std::is_void<Tp>::value, uint8_t, Tp>::type value;
// more properties
};
您可以像这样使用 typedef
或 using
:
using void_t = WrapData<void>;
using int_t = WrapData<int>;
// same as using
typedef WrapData<int> tp_int_t;
但只有using
可以使用模板:
// // compile error
// template<typename Tp>
// typedef WrapData<Tp> TpWrapData;
template<typename Tp>
using UsWrapData = WrapData<Tp>;
示例结构:
typedef struct tagExportSettings
{
COLORREF crHeading{};
COLORREF crEvenBack{};
COLORREF crOddBack{};
COLORREF crHighlight{};
COLORREF crDate{};
COLORREF crEvent{};
COLORREF crEmpty{};
COLORREF crNotes{};
} EXPORT_SETTINGS_S;
视觉助手说:
typedef
can be converted tousing
declaration.
更改此代码是否有真正的好处?
我在软件中的所有代码都使用 EXPORT_SETTINGS_S
,所以我不想破坏该语法。
更好的是什么都不用。一个类型名称就足够了。选择 tagExportSettings
或 EXPORT_SETTINGS_S
并坚持下去。示例:
struct tagExportSettings
{
// ...
};
But, 1. All my code in the software uses
EXPORT_SETTINGS_S
就像我说的,随便选一个名字。如果您使用 EXPORT_SETTINGS_S
,则将 class 命名为 EXPORT_SETTINGS_S
:
struct EXPORT_SETTINGS_S
{
// ...
};
如果某些内容仍然引用 tagExportSettings
,则重构代码以使用规范名称。
但更一般地说,using
优于 typedef
,因为它更具可读性。至少有两个原因:
使用
typedef
语法,不直观哪个是旧名称哪个是新别名:typedef new_or_old old_or_new; // old_or_new is the new alias
using
通过熟悉的初始化模式很直观:using intuitively_alias = intuitively_old_name;
typedef
对于复合名称,程序员很难解析语法,因为别名是“交错”的:// alias for void() typedef void function(); using function = void();
假设是纯 C++,这取决于您是否使用原始指针。如果不这样做,则只需在不使用 typedef
或 using
.
struct EXPORT_SETTINGS_S
{...
如果您经常使用原始指针并且在 Windows 中,习惯上不仅要定义别名,还要定义指针类型:
typedef struct tagExportSettings
{
...
} EXPORT_SETTINGS_S, *LPEXPORT_SETTINGS_S;
只有当您习惯了 LPXXX
"types" 时,这才重要。如果你是*
人,那就没必要了。
这些都不是 using
的 clear-cut 案例。
如果您使用 C++ 编写,using
会好得多。例如,像这样的模板结构:
template <typename Tp>
struct WrapData
{
const bool has_value = !std::is_void<Tp>::value;
typename std::conditional<std::is_void<Tp>::value, uint8_t, Tp>::type value;
// more properties
};
您可以像这样使用 typedef
或 using
:
using void_t = WrapData<void>;
using int_t = WrapData<int>;
// same as using
typedef WrapData<int> tp_int_t;
但只有using
可以使用模板:
// // compile error
// template<typename Tp>
// typedef WrapData<Tp> TpWrapData;
template<typename Tp>
using UsWrapData = WrapData<Tp>;