基于函数存在的模板行为

时间:2013-12-31 00:53:21

标签: c++ templates hashcode

我有一个模板类foo

template <typename Item>
class foo
{
    void method()
    {
        // ...
    }
}

我需要的是根据类型Item更改方法的实现,如果函数说unsigned int hasher(const Item& item)存在的话。

我的问题是 - 这在技术上是如何可能的,如果不是我如何组织代码来实现这个目标呢?

注意性能对算法来说是一个大问题,我正在寻找能够让编译器解决编译时差异的解决方案。

3 个答案:

答案 0 :(得分:1)

您需要应用模板策略,请查看: http://en.wikipedia.org/wiki/Policy-based_designC++ templates

答案 1 :(得分:0)

多年来没有触及c ++代码,所以不能当场给你写一个例子[也许我可以,但结果会很有趣]但正如this answer所指出的那样,你寻求的权力可以可以在SFINAE

中找到

答案 2 :(得分:0)

// Macro helper to create traits
#define HAS_TEMPLATED_FUNC(traitsName, funcName, Prototype)                          \
    namespace detail {                                                               \
    template<typename U>                                                             \
    class traitsName                                                                 \
    {                                                                                \
        typedef std::uint8_t yes;                                                    \
        typedef std::uint16_t no;                                                    \
        template <typename T, T> struct type_check;                                  \
        template <typename T = U> static yes &chk(type_check<Prototype, &funcName>*); \
        template <typename > static no &chk(...);                                    \
    public:                                                                          \
        static bool const value = sizeof(chk<U>(0)) == sizeof(yes);                  \
    };                                                                               \
    }                                                                                \
    template <typename U>                                                            \
    struct traitsName : std::conditional<detail::traitsName<U>::value,               \
                                         std::true_type, std::false_type>::type {}

现在假设:

unsigned int hasher(const int& item);

现在创建特征:

HAS_TEMPLATED_FUNC(has_hasher, hasher, unsigned int (*)(const T&));

// some test.
static_assert(has_hasher<int>::value, "");
static_assert(!has_hasher<char>::value, "");

现在,有一些方法可以使用它

标签调度:

template <typename Item>
class foo
{
public:
    void method()
    {
        method(has_hasher<Item>());
    }
private:
    void method(std::true_type)
    {
        // You may use hasher here.
        hasher(Item{});
    }
    void method(std::false_type)
    {
        // You cannot use hasher here.
    }
};

或SFINAE:

template <typename Item>
class foo
{
public:
    template <typename T = Item>
    typename std::enable_if<has_hasher<T>::value, void>::type
    method()
    {
        // You may use hasher here.
        hasher(Item{});
    }

    template <typename T = Item>
    typename std::enable_if<!has_hasher<T>::value, void>::type
    method()
    {
        // You cannot use hasher here.
    }
};