typedef 应该同时在类定义和类声明中吗?

Should a typedef be both in the class definition and class declaration?

本文关键字:声明 定义 typedef      更新时间:2023-10-16

我正在学习C++。我知道C++比大多数其他语言更冗长,但是在结构/类声明中定义typedef,然后在结构/类定义中再次定义让我思考是否没有更好或更中心的位置对于只需要定义一次的typedef,以及这是否遵循被认为是C++最佳实践。我在网上找不到任何关于这个特别的信息。

typedef移动到更全局的位置似乎不合适,并且typedef都用于结构中方法的定义和实现。

//--ProductFilter.h--
struct ProductFilter {
typedef std::vector<Product*> Items;
static Items by_color(Items items, Color color);
};
//--ProductFilter.cpp--
typedef std::vector<Product*> Items;
Items ProductFilter::by_color(Items items, Color color) {
Items result;
for (auto& item : items)
if (item->color == color)
result.push_back(item);
return result;
}

不需要在类声明和类定义中定义 typedef。 你这样做的原因是,当你这样做时

Items ProductFilter::by_color(Items items, Color color) {
Items result;
for (auto& item : items)
if (item->color == color)
result.push_back(item);
return result;
}

返回类型的Items范围不限于类,因此Items必须是全局范围内的名称。 如果您使用

ProductFilter::Items ProductFilter::by_color(Items items, Color color) {
Items result;
for (auto& item : items)
if (item->color == color)
result.push_back(item);
return result;
}

那么你不再有这个问题,你可以在类声明中使用 typedef。


你不需要做ProductFilter::Items的原因

ProductFilter::by_color(Items items, Color color)

这是因为ProductFilter::将您置于类的作用域中,因此您可以使用类中定义的名称,而无需对其进行限定。

你的定义应该是:

ProductFilter::Items ProductFilter::by_color(Items items, Color color)
{
// ...
}

或者,使用尾随返回类型:

auto ProductFilter::by_color(Items items, Color color) -> Items 
{
// ...
}

你的两个 typdef 实际上为同一类型声明了两个不同的别名。一个是ProductFilter::Items另一个Items全局命名空间中。

实际上,我不确定在ProductFilter范围内编写Items时会得到哪些规则,尽管这并不重要,因为它们无论如何都是相同的。

您只需要其中任何一个。选择哪一个取决于要在哪个范围内声明它。如果Items语义上属于ProductFilter那么我会选择第一个并将其仅放在声明中。

您必须将返回类型限定为ProductFilter::Items(或使用尾随返回类型(。

只需在类范围之外使用 typedef 的限定名

ProductFilter::Items ProductFilter::by_color(Items items, Color color) {
Items result;
for (auto& item : items)
if (item->color == color)
result.push_back(item);
return result;
}

出于实际原因,想要在 cpp 中获取该类的类型并没有错。你只是不应该重新定义,而是给它别名:

// top of cpp file
using Items = ProductFilter::Items;

如果项目类型发生更改,则无需重写别名。