【问题标题】:Should a typedef be both in the class definition and class declaration?typedef 是否应该同时在类定义和类声明中?
【发布时间】:2019-09-18 13:56:52
【问题描述】:

我正在学习 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;
}

【问题讨论】:

    标签: c++ class scope typedef


    【解决方案1】:

    你不需要在类声明和类定义中定义 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:: 将您置于类的范围内,因此您可以使用类中定义的名称而无需对其进行限定。

    【讨论】:

      【解决方案2】:

      你的定义应该是:

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

      或者,带有尾随返回类型:

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

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

          【解决方案4】:

          只使用类范围之外的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;
          }
          

          【讨论】:

          • auto ProductFilter::by_color(Items items, Color color) -&gt; Items
          【解决方案5】:

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

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

          如果项目的类型发生变化,则不需要重写别名。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-05-28
            • 2014-11-11
            • 2012-09-27
            • 2013-06-02
            • 1970-01-01
            • 1970-01-01
            • 2014-05-27
            • 2014-12-05
            相关资源
            最近更新 更多