c++ - 使用 C++ 模板切换策略/算法

标签 c++ templates strategy-pattern

我有一个 C++ 类可以用于线性或二进制搜索。

目前我有额外的成员变量显示要使用的搜索。

我知道如何使用类似 Java 的虚函数(策略模式或模板方法)进行搜索,
但我很好奇在编译时使用模板<> 完成此操作的最佳做​​法是什么?

当前(简化的)代码如下所示:

int MyArray::lookup(const String &key) const{
    if (lookupMethod == LINEAR_SEARCH)
        return lookupLinearSearch(key);
    else
        return lookupBinarySearch(key);
}

最佳答案

最明显的方法是将策略封装在类型中并将 lookup() 实现为函数模板:

namespace searchStrategy {
    struct linearSearch {
        static auto lookup(const MyArray& a, const String &key)
        -> int {
            return a.lookupLinearSearch(key);
        };
    };

    struct binarySearch {
        static auto lookup(const MyArray& a, const String &key)
        -> int {
            return a.lookupBinarySearch(key);
        };
    };
}

class MyArray {
    public:
        template <typename LookupStrategy>
        auto lookup(const String &key) const
        -> int {
            return LookupStrategy::lookup(*this, key);
        };
};

// ...
auto myArray = MyArray{};
mArray.lookup<searchStrategy::binarySearch>("asdf"s);

或者,您可以专门化模板并将策略类型仅用作标记:

namespace searchStrategy {
    struct linearSearch {};    
    struct binarySearch {};
}

class MyArray {
    public:
        template <typename LookupStrategy>
        int lookup(const String &key) const;
        template <>
        int lookup<searchStrategy::linearSearch>(const String &key) const {
            return lookupLinearSearch(key);
        };
        template <>
        int lookup<searchStrategy::binarySearch>(const String &key) const {
            return lookupBinarySearch(key)
        };
};


// ...
auto myArray = MyArray{};
mArray.lookup<searchStrategy::binarySearch>("asdf"s);

现在您可能更愿意不必定义模板参数,而是使用函数参数。你甚至不需要模板,只需要方法重载:

namespace searchStrategy {
    struct LinearSearchT {};    
    struct BinarySearchT {};
    static const LinearSearchT linearSearch;
    static const BinarySearchT binarySearch;
}

class MyArray {
    public:
        int lookup(const String &key,
                   const searchStrategy::linearSearchT strategy) const {
            return lookupLinearSearch(key);
        };
        int lookup(const String &key,
                   const searchStrategy::binarySearchT strategy) const {
            return lookupBinarySearch(key)
        };
};


// ...
auto myArray = MyArray{};
mArray.lookup("asdf"s, searchStrategy::binarySearch);

看起来像是动态选择策略,但实际上是静态的。你不能做这样的事情:

mArray.lookup("asdf"s, (someReason) ?
                           searchStrategy::binarySearch :
                           searchStrategy::linearSearch);

在那种情况下你必须写

if( someReason )
    mArray.lookup("asdf"s, searchStrategy::binarySearch);
else
    mArray.lookup("asdf"s, searchStrategy::linearSearch);

注意:此答案中的所有代码都未经测试。它将包含错误。

关于c++ - 使用 C++ 模板切换策略/算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33263375/

相关文章:

c++ - 模板化类然后重载运算符 (C++)

c++ - 制作现有模板类的模板

java - 'Strategy pattern'可以用Java注解实现吗?

oop - 策略模式和访问者模式有什么区别?

c++ - boost::polygon 和 boost/geometry/geometries/polygon 区别?

c++ - 如何分离 `QObject` 的父子关系的关注点,例如与其他所有者互操作?

c++编译器如何知道参数是STL容器?

java - 删除作为策略模式一部分的条件代码

c++ - 禁用部分代码的简单方法

c++ - Opengl 3.3 不绘制任何东西。使用 GLSL 330 核心