定义专用类的不完整结构

时间:2013-07-20 00:33:53

标签: c++ specialization incomplete-type

我在类专业化中声明一个不完整的结构并稍后定义它时遇到了问题。

struct Foo {
    template <bool Y, typename D>
    struct Bar {};

    template <typename D>
    struct Bar<true, D> {
        struct Qux;
    };

    template <typename D>
    struct Bar<true, D>::Qux { int x; };
};

此代码适用于gcc,但在clang 3.3中失败:

r.cpp:42:26: error: non-friend class member 'Qux' cannot have a qualified name
    struct Bar<true, D>::Qux { int x; };
           ~~~~~~~~~~~~~~^

如果代码是在命名空间范围内编写的(没有struct Foo),那么它也适用于clang。

另一方面,如果将struct Foo转换为模板,如下所示,代码在gcc-4.9(未发布)中断,尽管它在gcc-4.7中保持有效。

template <typename X>
struct Foo {
    template <bool Y, typename D>
    struct Bar {};

    template <typename D>
    struct Bar<true, D> {
        struct Qux;
    };

    template <typename D>
    struct Bar<true, D>::Qux { int x; };
};

Clang失败了:

r.cpp:43:26: error: template specialization or definition requires a template parameter list corresponding to the nested type 'Bar<true, type-parameter-1-0>'
    struct Bar<true, D>::Qux { int x; };
                         ^
r.cpp:43:26: error: non-friend class member 'Qux' cannot have a qualified name
    struct Bar<true, D>::Qux { int x; };
           ~~~~~~~~~~~~~~^
2 errors generated.

Gcc-4.9失败并出现类似错误:

r.cpp:43:26: error: too few template-parameter-lists
     struct Bar<true, D>::Qux { int x; };
                          ^

2 个答案:

答案 0 :(得分:2)

看起来您没有选择,只能将该定义放在命名空间范围内(或Bar内)。第9/1段(n3337)说你的代码是非法的:

  

如果 class-head-name 包含嵌套名称指定 class-speci fi er 应该指的是一个类   以前直接在嵌套名称指定者引用的类或命名空间中声明,或者在   该命名空间的内联命名空间集(7.3.1)的元素(即,不仅仅是由...继承或引入   a using-declaration ), class-speci fi er 应出现在包含上一个声明的命名空间中。   在这种情况下,定义的 class-head-name 嵌套名称指定不应以    decltype-SPECI音响ER

答案 1 :(得分:-3)

struct Foo {
  template <bool Y, typename D>
  struct Bar {};
};

template <typename D>
struct Foo::Bar<true, D> {
  struct Qux;
};

template <typename D>
struct Foo::Bar<true, D>::Qux {
  int x;
};