繁体   English   中英

模板类中基于整数范围的模板方法的专业化

[英]Integer range based specialization of template method in template class

有什么方法可以对整数模板类中的模板函数进行范围专门化? 经过大量研究,我觉得答案可能只是“否”,但也许有一个巧妙的窍门或解决方法。

我尽可能简化了课堂,以演示这个问题。

template<int value>
class MyClass
{
    template <typename T, typename X>
    uint64_t foo()
    {
        static_assert(sizeof(T) == 0, "Unsupported type combination.");
        return 0;
    }

    uint64_t m_member;
};

到目前为止非常容易。 非专业的实现使用静态断言,因为我只希望将模板函数用于某些类型。 这些函数在类定义之外是专用的。

template<>
template<>
uint64_t MyClass<1>::foo<uint8_t, uint16_t>()
{
    return m_member * 1000;
}

template<>
template<>
uint64_t MyClass<7>::foo<uint8_t, uint16_t>()
{
    return m_member * 7000;
}

不,我正在寻找一种解决方案,以在一定范围的val中使用此专业化功能。 我希望MyClass <0>抛出静态断言,MyClass <1>,MyClass <2>,...,MyClass <6>应该使用MyClass <1>,最后MyClass <7>必须使用第二种特殊化。 foo的其他专业化工作也有所不同。 我有很多像foo这样的函数,并且每个函数的确有大约10种类型组合,并且它们的工作方式都非常不同。

最简单的解决方法是简单地复制专业知识,但是我希望有一个更好的解决方案。 如果可以将foo保留为模板函数会很好,但是我也可以使用定义foo的所有可能组合的解决方案,例如foo_u8_u16();、 foo_u32_u64(),...

这应该工作:

template<int value, class T, class X>
struct Helper {
    static uint64_t foo(uint64_t param) {
        return Helper<value - 1, T, X>::foo(param);
    }
};

template<class T, class  X>
struct Helper<0, T, X> {
    static uint64_t foo(uint64_t param) {
        static_assert(sizeof(T) == 0, "Unsupported type combination.");
        return 0;
    }
};

template<>
uint64_t Helper<1, uint8_t, uint16_t>::foo(uint64_t param) {
    return param * 1000;
}

template<>
uint64_t Helper<7, uint8_t, uint16_t>::foo(uint64_t param) {
    return param * 7000;
}

template<int value>
class MyClass {
    template<class T, class X>
    uint64_t foo() {
        return Helper<value, T, X>::foo(m_member);
    }

    uint64_t m_member;
};

你可以这样做:

#include <type_traits>

// the implementation of foo is moved to a different class

template<int value, typename = void>
struct FooImpl
{
    template <typename T, typename X>
    uint64_t foo()
    {
        static_assert(sizeof(T) == 0, "Unsupported type combination.");
        return 0;
    }
};

// partial specialization that will be enabled
// when value is in range [1,6)

template<int value>
    typename =  typename std::enable_if<value > 0 && value < 7>::type>
struct FooImpl<value,
        typename std::enable_if<(value > 0 && value < 7)>::type>
{
    template <typename T, typename X>
    uint64_t foo()
    {
        return 1000;
    }
    // you can write several overloads instead of a template, too
};

// now inherit from FooImpl

template<int value>
class MyClass : private FoomImpl<value>
{
    // write a forwarding function for foo here
    // or just a using declaration
};

希望能对您有所帮助,并且我能正确理解您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM