用于复杂类型的单一方法的 C++ 模板特化

标签 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。

最佳答案

执行此操作有多种选择,我会选择哪一种取决于我希望这种特殊行为可定制的程度。对于您在此处展示的内容,我可能会使用重载函数:

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/

相关文章:

c++ - MESI协议(protocol)&std::atomic-是否可以确保所有写操作立即对其他线程可见?

模板类中的 C++20 类外定义

c++ - 没有用于调用 std::vector<std::tuple> push_back 的匹配函数

javascript - 如何停止在 node.js 中获取此 ReferenceError?

c++ - 使用运行时常量实例化的函数模板

c++ - OpenCV 捕获视频 Ubuntu 12.0.4

c++ - 使用 OpenMP C++ 并行化程序以计算积分

c++ - 右值或左值 (const) 引用参数

c++ - 如何从嵌套类访问成员变量

c++ - 模板类的类型定义?