我想为数值创建一个模板,对于给定的类型,我想提供最小值和最大值的默认值。
我找到了一个迄今为止有效的解决方案......
template<typename T> struct MinDefaultValue;
template<typename T> struct MaxDefaultValue;
template<typename T, usize_t MinDefault = MinDefaultValue<T>::value, usize_t MaxDefault = MaxDefaultValue<T>::value>
class NumericColumn
{
public:
public:
NumericColumn(T *pAddress, T nDefault, usize_t nMinValue = MinDefault, usize_t nMaxValue = MaxDefault)
{
mAddress = pAddress;
mDefault = nDefault;
mMinValue = nMinValue;
}
bool toValue(void)
{
return true;
}
private:
T *mAddress;
usize_t mMinValue;
usize_t mMaxValue;
T mDefault;
};
template <> struct MinDefaultValue<byte_t> { static const usize_t value = (usize_t)CHAR_MIN; };
template <> struct MaxDefaultValue<byte_t> { static const usize_t value = (usize_t)CHAR_MAX; };
我不喜欢它的原因是,因为现在Min-
和MaxDefaultValue
在类名称空间之外,而它属于它。
我遇到的问题是我不知道如何为各种类型定义特化,因为父类本身也是一个模板。
我将课程改为:
template<typename T>
class NumericColumn
{
public:
template<typename T> struct MinDefaultValue;
template<typename T> struct MaxDefaultValue;
public:
NumericColumn(T *pAddress, T nDefault, usize_t nMinValue = MinDefaultValue<T>::value, usize_t nMaxValue = MaxDefaultValue<T>::value)
{
mAddress = pAddress;
mDefault = nDefault;
mMinValue = nMinValue;
}
bool toValue(void)
{
return true;
}
private:
T *mAddress;
usize_t mMinValue;
usize_t mMaxValue;
T mDefault;
};
但是当我尝试提供spezialisations时,我收到编译器错误:
template <> struct NumericColumn<byte_t>::MinDefaultValue<byte_t> { static const usize_t value = (usize_t)CHAR_MIN; };
template <> struct NumericColumn<byte_t>::MaxDefaultValue<byte_t> { static const usize_t value = (usize_t)CHAR_MAX; };
'class' : invalid or missing type parameter list
答案 0 :(得分:2)
我认为你的第二种方法并不是你的意思。将MinDefaultValue
和MaxDefaultValue
作为内部模板类意味着每个NumericColumn<T>
模板实例化都将具有单独的模板类。因此,NumericColumn<int>::MaxDefaultValue<int>
是与NumericColumn<float>::MaxDefaultValue<float>
不同的类型。
也许你想要的是一个简单的static const
成员,你专门针对每种类型:
template<typename T>
class NumericColumn
{
public:
static const std::size_t MinDefaultValue;
static const std::size_t MaxDefaultValue;
public:
NumericColumn(T *pAddress, T nDefault,
std::size_t nMinValue = MinDefaultValue,
std::size_t nMaxValue = MaxDefaultValue)
: mAddress{pAddress}, mDefault{pDefault},
mMinValue{nMinValue}, mMaxValue{mMaxValue}
{ }
};
template<>
const std::size_t NumericColumn<int>::MinDefaultValue = 1;
template<>
const std::size_t NumericColumn<int>::MaxDefaultValue = 10;
请注意,如果您没有为某些NumericType
专门化定义成员专精,那么在实例化时会出现链接错误。也许这就是你想要的,也许不是。
这是一种以牺牲一些简洁为代价获得更好的错误消息的可能方法:
template <typename T>
struct dependent_false : std::false_type {};
template<typename T>
class NumericColumn
{
public:
struct MinDefault{
static_assert(dependent_false<T>::value,
"T does not have a minimum default defined");
};
struct MaxDefault{
static_assert(dependent_false<T>::value,
"T does not have a maximum default defined");
};
public:
NumericColumn(T *pAddress, T nDefault,
std::size_t nMinValue = MinDefault::value,
std::size_t nMaxValue = MaxDefault::value)
: mAddress{pAddress}, mDefault{pDefault},
mMinValue{nMinValue}, mMaxValue{mMaxValue}
{ }
};
template<>
struct NumericColumn<int>::MinDefault {
static constexpr std::size_t value = 1;
};
template<>
struct NumericColumn<int>::MaxDefault {
static constexpr std::size_t value = 10;
};
答案 1 :(得分:0)
我认为你不能专门化模板类中的模板。我希望知道c ++标准的人比我能说的更好。
您可以使用访问垫片:
template <typename TColumn, typename T> inline T MinDefaultValue();
// specialization:
template <> inline byte_t MinDefaultValue<NumericColumn<byte_t>,byte_t> () {
return 5;
}
您可以通过在列类型中添加typedef来降低此值:
typedef T value_type;
然后是:
template <typename TColumn> inline typename T::value_type MinDefaultValue();
// specialization:
template <> inline byte_t MinDefaultValue<NumericColumn<byte_t> > () {
return 5;
}
然后,然后允许对列类类型的最小值进行特化。
如果没有专业化,这将失败。