我有一个像这样的抽象类和子类:
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>>
, 其中X
和 Y
可以是任何类型,我想要这个实现:
bool shouldDoIt() {
if(state) return true;
for(auto &member : val) {
if(member.second->state) return true;
}
return false;
}
我如何专门为这些类型实现 shouldDoIt()?我正在使用 Visual Studio 2015。
最佳答案
执行此操作有多种选择,我会选择哪一种取决于我希望这种特殊行为可定制的程度。对于您在此处展示的内容,我可能会使用重载函数:
template <class T>
class MyClass : public MyAbstractClass {
public:
bool shouldDoIt() {
if (state) return true;
return specializedShouldDoIt(val);
}
private:
template <class U>
static bool specializedShouldDoIt(U&) { return false; }
template <class X>
static bool specializedShouldDoIt(
std::vector<std::shared_ptr<MyClass<X>>> &val) {
// your loop is equivalent to std::any_of
return std::any_of(val.begin(), val.end(), [](auto &member) {
return member->state;
});
}
template <class X, class Y>
static bool specializedShouldDoIt(
std::unordered_map<X, std::shared_ptr<MyClass<Y>>> &val) {
return std::any_of(val.begin(), val.end(), [](auto &member) {
return member.second->state;
});
}
};
我可能会考虑的另一种选择是拥有一个外部辅助类,这样我就可以使用部分特化:
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);
}
};
关于用于复杂类型的单一方法的 C++ 模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49781561/