使用基于类型的默认参数创建模板

时间:2015-11-19 13:44:33

标签: c++ templates

我想为数值创建一个模板,对于给定的类型,我想提供最小值和最大值的默认值。

我找到了一个迄今为止有效的解决方案......

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

2 个答案:

答案 0 :(得分:2)

我认为你的第二种方法并不是你的意思。将MinDefaultValueMaxDefaultValue作为内部模板类意味着每个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;
}
然后,

然后允许对列类类型的最小值进行特化。

如果没有专业化,这将失败。