C ++与部分模板特化语法混淆

时间:2017-02-04 23:21:28

标签: c++ templates

有没有办法可以避免使用Range2作为名称并将这两个类命名为Range?我对C ++模板语法有点困惑。

template <int BEGIN, int END>
class Range2
{
public:
    class Iterator
    {
    private:
        int n;

    public:
        Iterator(int n)
            : n(n)
        {
        }

        int operator *() const
        {
            return n;
        }

        Iterator const & operator ++()
        {
            ++n;
            return *this;
        }

        bool operator !=(Iterator const & i) const
        {
            return n != i.n;
        }
    };

    Iterator begin() const
    {
        return Iterator(BEGIN);
    }

    Iterator end() const
    {
        return Iterator(END);
    }
};

template<int END>
class Range
    : public Range2<0, END>
{
};

1 个答案:

答案 0 :(得分:1)

与函数参数一样,在C ++模板中,参数可以具有默认值。在BEGIN之前,只有默认值为0的情况下,你必须支付这个没有默认值的END。

// Here we add the default parameter to BEGIN
// The arguments are switched because END is without a default       
// parameter, so it has to come before BEGIN that has one
template <int END, int BEGIN=0>
// The class itself is the same, but now you can use it
// without giving a BEGIN parameters
class Range
{
public:
    class Iterator
    {
    private:
        int n;

    public:
        Iterator(int n)
            : n(n)
        {
        }

        int operator *() const
        {
            return n;
        }

        Iterator const & operator ++()
        {
            ++n;
            return *this;
        }

        bool operator !=(Iterator const & i) const
        {
            return n != i.n;
        }
    };

    Iterator begin() const
    {
        return Iterator(BEGIN);
    }

    Iterator end() const
    {
        return Iterator(END);
    }
};

它编译并应按预期工作。没有主要的,我无法测试它。

编辑:我添加了一些评论,这里是一个使用示例,仅为了清晰起见:

Range<10, 3> r(3); /*here we use it as usual, pay attention begin is 
                     now the second argument and not the first */
Range<10> r(0);    /* here we don't give a BEGIN argument, the 
                      compiler will use the default one */