typedef 是否应该同时出现在 class 定义和 class 声明中?
Should a typedef be both in the class definition and class declaration?
我正在学习 C++。我知道 C++ 比大多数其他语言更冗长,但是在 struct/ class 声明中定义 typedef
然后在 struct/ class 定义中再次定义让我思考是否有对于 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;
}
您的两个 typdef 实际上为同一类型声明了两个不同的别名。一个是 ProductFilter::Items
,另一个是全局命名空间中的 Items
。
实际上我不确定在 ProductFilter
范围内写 Items
时得到的规则是什么,尽管这并不重要,因为它们是相同的。
你只需要其中一个。您选择哪一个取决于您要在哪个范围内声明它。如果 Items
在语义上属于 ProductFilter
那么我会选择第一个并将其仅放在声明中。
您必须将 return 类型限定为 ProductFilter::Items
(或使用尾随 return 类型)。
只需在 class 范围外使用 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;
}
您不需要在 class 声明和 class 定义中定义 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;
}
return 类型的 Items
不在 class 范围内,因此 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;
}
那么你不再有这个问题,你可以在 class 声明中使用 typedef。
您不需要在
中执行 ProductFilter::Items
的原因
ProductFilter::by_color(Items items, Color color)
是因为 ProductFilter::
将您置于 class 的范围内,因此您可以使用 class 中定义的名称而无需限定它们。
您的定义应该是:
ProductFilter::Items ProductFilter::by_color(Items items, Color color)
{
// ...
}
或者,使用尾随 return 类型:
auto ProductFilter::by_color(Items items, Color color) -> Items
{
// ...
}
出于实际原因,想要从 cpp 中的 class 中获取类型并没有错。你只是不应该重新定义,而是别名:
// top of cpp file
using Items = ProductFilter::Items;
如果项目的类型发生变化,则不需要重写别名。
我正在学习 C++。我知道 C++ 比大多数其他语言更冗长,但是在 struct/ class 声明中定义 typedef
然后在 struct/ class 定义中再次定义让我思考是否有对于 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;
}
您的两个 typdef 实际上为同一类型声明了两个不同的别名。一个是 ProductFilter::Items
,另一个是全局命名空间中的 Items
。
实际上我不确定在 ProductFilter
范围内写 Items
时得到的规则是什么,尽管这并不重要,因为它们是相同的。
你只需要其中一个。您选择哪一个取决于您要在哪个范围内声明它。如果 Items
在语义上属于 ProductFilter
那么我会选择第一个并将其仅放在声明中。
您必须将 return 类型限定为 ProductFilter::Items
(或使用尾随 return 类型)。
只需在 class 范围外使用 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;
}
您不需要在 class 声明和 class 定义中定义 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;
}
return 类型的 Items
不在 class 范围内,因此 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;
}
那么你不再有这个问题,你可以在 class 声明中使用 typedef。
您不需要在
中执行ProductFilter::Items
的原因
ProductFilter::by_color(Items items, Color color)
是因为 ProductFilter::
将您置于 class 的范围内,因此您可以使用 class 中定义的名称而无需限定它们。
您的定义应该是:
ProductFilter::Items ProductFilter::by_color(Items items, Color color)
{
// ...
}
或者,使用尾随 return 类型:
auto ProductFilter::by_color(Items items, Color color) -> Items
{
// ...
}
出于实际原因,想要从 cpp 中的 class 中获取类型并没有错。你只是不应该重新定义,而是别名:
// top of cpp file
using Items = ProductFilter::Items;
如果项目的类型发生变化,则不需要重写别名。