递归嵌套模板 - gcc bug?

时间:2011-05-01 21:42:54

标签: c++ templates gcc

我有以下代码段。

template< typename T >
struct f
{
  template< typename V >
  struct a : f
  {};
};

int main ()
{
  f<int>::a<int>::a<double> x;
}

它在GCC 4.4.5和MSVC 2010上没有警告编译,但在GCC 4.5.2上没有 - 我得到以下错误:

test.cc: In function 'int main()':
test.cc:11:21: error: expected primary-expression before 'double'
test.cc:11:21: error: expected ';' before 'double'

所以虽然我没有看到任何关于它的非标准,但问题是强制性的 - 这在C ++中是合法的吗?此外,如果是,我如何在GCC提交错误报告? (:

编辑:好奇的一点背景:

这应该是一个模板元编程。 f基本上具有模板元函数类的结构,其中apply替换为a(当然,type的嵌套apply被省略,因此我们可以专注于结构本身)。

在这种情况下,继承是用于绑定元函数返回值的标准设备。这个代码片段试图实现的是一个元函数类,它在评估时以递归方式自我产生。

edit2 :让我对相同的代码段略有不同:

template< typename T >
struct f
{
  template< typename V > struct a;
};

template< typename T >
template< typename V >
struct f<T>::a : f<T>
{};

int main ()
{
  f<int>::a<int>::a<double> x;
}

这会产生相同的错误。我认为它驳斥了不完整的类型参数。

4 个答案:

答案 0 :(得分:4)

现有答案中有几个好的笔记。首先,f的类型在定义嵌套类模板时是不完整的,但f是依赖类型。现在,如果您实例化嵌套模板(f),它将实例化嵌套模板(成员)的声明。请注意,成员的声明不包括基本子句列表,因此它不需要完整的基类。一旦嵌套模板被隐式实例化,f就完成了,当涉及实例化成员的定义时,应该没有问题了。所以我不认为这里的抱怨是正确的抱怨。

另一个错误是,事实上,f<int>::a<int>::a正在命名a<int>的构造函数,并要求它是一个构造函数模板(<int>是模板参数)。其基础是DR #147

当限定符名称不是注入的类名的类时,不会转换到构造函数。例如,如果它是派生类,则代码变为有效(如某些答案所示)。

答案 1 :(得分:2)

好问题。这似乎是gcc template递归声明的问题。因为,如果有固体类,那么它会给出错误,理想情况下它应该声明为:

struct Out {
  struct In;
};
struct Out::In : Out {};

答案 2 :(得分:1)

看起来GCC 4.5认为你已经指定了构造函数。

一种可能的解决方法:

template<typename T>
struct f {

    template<typename V>
    struct a : f {

        template<typename Z>
        struct q {
            typedef a<Z> Q;
        };
    };
};

int main() {
    f<int>::a<int>::q<double>::Q x;
    return 0;
}

答案 3 :(得分:0)

在线使用Comeau,它表明f在您将其用作基类时是不完整的类型,因此不适合。

"ComeauTest.c", line 5: error: incomplete type is not allowed
    struct a : f

不幸的是,我手头没有clang实例。