模板化循环类型错误 [英] Templated recurrent type error

查看:118
本文介绍了模板化循环类型错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临着一个奇怪的问题VS2010。以下代码无法编译(完全被gcc 接受):

I am facing a weird problem with VS2010. The following code fails to compile (while being perfectly accepted by gcc):

// Instantiate each type of a type array (which is a template<int>)
// void is taken as the end of the array
template<template<int> class A, int n = 0, typename obj_type = typename A<n>::type>
struct Instantiate : public Instantiate<A,n+1>
{
   obj_type object;

   Instantiate() : object() {}
};

template<template<int> class A, int n>
struct Instantiate<A,n,void>
{
};

// Does not compile
template<typename O>
struct test
{
   template<int n, bool=true> struct array { typedef void type; };
   template<int n> struct array2 { typedef typename array<n>::type type; };

   template<bool u> struct array<0,u> { typedef int type; };
   template<bool u> struct array<1,u> { typedef float type; };
   template<bool u> struct array<2,u> { typedef bool type; };

   Instantiate<array2> objects;
};

int main()
{
   test<int> obj;
}

出现以下错误:

C1202: recursive type or function dependency context too complex
see instanciation of class template 'Instantiate<A,n>'
with
[
    A=test<O>::array2,
    n=1
]
(and so on, up to n=497...)

使 test 一个非模板c $ c> template< typename O> )解决错误。然而,尽管在这个简单的例子中是可能的,但在我的代码中是不可能的(这是非常复杂的)。

Making test a non-template (ie, juste removing the line template<typename O>) solves the error. However, despite it is possible in this simple example, it is not possible in my code (which is a lot more complex).

问题是: / strong>

The questions are:


  • 这是正确的,VS还是GCC?

  • Which is right, VS or GCC ? Or is it a VS bug ?
  • In the case VS is wrong, is there a workaround ?

编辑
- 从jerry的回答,似乎它是一个编译器错误...它是固定的VS2012。
- 生成的类层次结构应为:

EDIT: - From jerry's answer, it seems it is a compiler bug... and it is fixed on VS2012. - The generated class hierarchy should be:

Instantiate<array2, 3, void> // end of recursion
      ^
      |
Instantiate<array2, 2, bool>
      ^
      |
Instantiate<array2, 1, float>
      ^
      |
Instantiate<array2, 0, int>


推荐答案

在解决rise4fun和jerry的解决方法时,将实例化 的整个定义放在 test 解决问题请参阅jerry的答案有关VS2012CTP VS VS2012RTM 的更多信息):

While messing with rise4fun and jerry's workaround, I found that putting the whole definition of Instantiate inside test 'solved' the problem (see jerry's answer for more information on VS2012CTP vs VS2012RTM):

template<typename O>
struct test
{
    template<template<int> class A, int n = 0, typename obj_type = typename A<n>::type>
    struct Instantiate : public Instantiate<A,n+1>
    {
        obj_type object;
        Instantiate() : object() {}
    };

    template<template<int> class A, int n>
    struct Instantiate<A,n,void>
    {
    };

    template<int n, bool=true> struct array { typedef void type; };
    template<int n> struct array2 { typedef typename array<n>::type type; };

    template<bool u> struct array<0,u> { typedef int type; };
    template<bool u> struct array<1,u> { typedef float type; };
    template<bool u> struct array<2,u> { typedef bool type; };

    Instantiate<array2> objects;
};

int main()
{
   test<int> obj;
}

这是完美的我的用例,因为它可以包含在一个宏用户使用。

Which is perfect for my use case as it can be included in a macro already used by the user.

这篇关于模板化循环类型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆