有没有办法在整数模板类中对模板函数进行范围特化?经过大量的研究后,我感觉答案可能只是简单而不是#34;但也许有一个巧妙的技巧或解决方法。
我尽可能地简化了我的课程来证明这个问题。
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&lt; 0&gt;抛出静态断言,MyClass&lt; 1&gt;,MyClass&lt; 2&gt;,...,MyClass&lt; 6&gt;应该使用MyClass&lt; 1&gt;最后,MyClass&lt; 7&gt;必须使用第二个专业化。 foo 的其他专业不同。我有很多函数,比如 foo ,所有函数都有大约10种类型组合,并且它们的工作方式都非常不同。
最简单的解决方法是简单地复制专业化,但我希望有更好的解决方案。如果将 foo 保存为模板函数会很好,但我也可以使用定义 foo 的所有可能组合的解决方案,例如foo_u8_u16();, foo_u32_u64(),...
答案 0 :(得分:0)
这应该有效:
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;
};
答案 1 :(得分:0)
你可以这样做:
#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
};
希望这有助于我理解你的问题。