复杂类型的单个方法的C ++模板专门化

时间:2018-04-11 17:52:07

标签: c++ c++11 templates

我有一个像这样的抽象类和子类:

class MyAbstractClass {
public:
    virtual bool shouldDoIt() = 0;
}

template <class T> class MyClass : public MyAbstractClass {
public:

    bool shouldDoIt() { return state; }

private: // assume there are appropriate accessors for these private fields
    bool state;
    T val;
}

shouldDoIt()的这种实现适用于大多数类型。但如果T碰巧是std::vector<std::shared_ptr<MyClass<X>>>,其中X可以是任何类型,那么我希望实现是这样的:

bool shouldDoIt() {
    if(state) return true;
    for(auto &member : val) {
        if(member->state) return true;
    }
    return false;
}

如果它是std::unordered_map<X, std::shared_ptr<MyClass<Y>>,其中XY可以是任何类型,我想要这个实现:

bool shouldDoIt() {
    if(state) return true;
    for(auto &member : val) {
        if(member.second->state) return true;
    }
    return false;
}

我如何专门针对这些类型实现shouldDoIt()?我正在使用Visual Studio 2015。

1 个答案:

答案 0 :(得分:1)

有几个选项可以做到这一点,我选择哪一个取决于我希望这个特殊行为可以自定义多少。根据你在这里展示的内容,我可能会使用一个重载函数:

template <class T>
struct PerformShouldDoIt
{
    static bool shouldDoIt(bool state, T&) { return state; }
};

template <class X>
struct PerformShouldDoIt<std::vector<std::shared_ptr<MyClass<X>>>>
{
    static bool shouldDoIt(bool state,
                           std::vector<std::shared_ptr<MyClass<X>>>& val) {
        return std::any_of(val.begin(), val.end(), [](auto &member) {
            return member->state;
        });
    }
};

// Similarly for whatever you wanted to specialize for

...

template <class T>
class MyClass : public MyAbstractClass {
public:

    bool shouldDoIt() {
        return PerformShouldDoIt<T>::shouldDoIt(state, val);
    }
};

我可能考虑的另一个选择是拥有一个外部帮助器类,以便我可以使用部分特化:

  {
    "_index": "items_production_20180411115923024",
    "_type": "item",
    "_id": "1232",
    "_score": 21.715849,
    "_source": {
      "description": "CUBO RODA TRASEIRA VW:GOL, VOYAGE G5/G6 09> C/ABS",
      "observation": null,
      "brand_id": "1 ",
      "product_line_id": "13",
      "line_id": "1",
      "line": "Rolamentos",
      "segment_id": "21",
      "segment": "cubo de roda",
      "application_features": [
        "4 furos"
      ],
      "original_codes": [
        " 5u0 501 611 "
      ],
      "original_brands": [
        "volkswagen"
      ],
      "vehicles": [
        {
          "id": "285",
          "brand": "volkswagen",
          "name": "golf",
          "years": [
            "2009",
            "2010",
            "2011",
            "2012",
            "2013",
            "2014",
            "2015",
            "2016",
            "2017",
            "2018"
          ]
        },
        {
          "id": "345",
          "brand": "volkswagen",
          "name": "jetta",
          "years": [
            "2015",
            "2016",
            "2017",
            "2018"
          ]
        }
      ]
    }
  }