生成编译时整数范围时的不完整类型

时间:2014-12-21 11:37:33

标签: c++ templates

我无法生成编译时整数范围。这是我的代码:

#include<type_traits>
#include<iostream>
using namespace std;

// this is needed because I'm using vs2013
template<typename T, T...Seq>
struct integer_sequence{
    using type = integer_sequence<T, Seq...>;
};

template<typename T>
struct ToMemberType {
    using type = T;
};


template<typename TTest, typename TCount, typename TResult>
struct ImplMakeIntegerRange;

template<typename T, T Begin, T End, T...Seq>
struct ImplMakeIntegerRange<
        integer_sequence<T, Begin>,
        integer_sequence<T, End>,
        integer_sequence<T, Seq...>
    >
    :
    conditional<
        is_same<
            integer_sequence<T, Begin>,
            integer_sequence<T, End>
        >::value,
        integer_sequence<T, Seq...>,
        ToMemberType <
            ImplMakeIntegerRange<
                integer_sequence<T, Begin>,
                integer_sequence<T, End - 1>,
                integer_sequence<T, End - 1, Seq...>
            >
        >
    >::type {
    static_assert(Begin <= End, "Begin <= End failed");
};

template<typename T, T Begin, T End>
using make_integer_range =
    typename ImplMakeIntegerRange <
        integer_sequence<T, Begin>,
        integer_sequence<T, End>,
        integer_sequence < T >
    >::type;

// the code below is to test if make_integer_range really works.
template<typename T>
struct PrintIntegerRange;

template<typename T, T...Seq>
struct PrintIntegerRange<integer_sequence<T, Seq...>>{
public:
    static void Print() {
        for (auto a : { Seq... }) {
            cout << a << ' ';
        }
        cout << endl;
    }
};


int main()
{
    //I expect this two print the same result.
    PrintIntegerRange<integer_sequence<int, 3, 4, 5>>::Print();
    PrintIntegerRange<make_integer_range<int, 3, 6>>::Print(); //got three error here.

}

上面的代码从未编译过。最后一行产生三条错误消息:

  1. 错误C2027:使用未定义类型'PrintIntegerRange'
  2. 错误C3861:'打印':未找到标识符
  3. 智能感知:不允许使用不完整类型
  4. 同样,我正在使用vs2013。我哪里错了?

    编辑: PS。如果最后一行被删除,代码将编译并获得预期结果。

1 个答案:

答案 0 :(得分:0)

我认为问题在于使用ToMemberType结构。您必须从ImplMakeIntegerRange定义中删除它或者像这样提取其模板参数类型

template<typename T, T Begin, T End, T...Seq>
struct ImplMakeIntegerRange<
        integer_sequence<T, Begin>,
        integer_sequence<T, End>,
        integer_sequence<T, Seq...>
    >
    :
    conditional<
        is_same<
            integer_sequence<T, Begin>,
            integer_sequence<T, End>
        >::value,
        integer_sequence<T, Seq...>,
        typename ToMemberType <
            ImplMakeIntegerRange<
                integer_sequence<T, Begin>,
                integer_sequence<T, End - 1>,
                integer_sequence<T, End - 1, Seq...>
            >
        >::type
    >::type {
    static_assert(Begin <= End, "Begin <= End failed");
};