3

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

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; };
                          ^
4

2 回答 2

2

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

如果一个类头名称包含一个嵌套名称说明符,则该类说明符应引用先前直接在嵌套名称说明符所引用的类或命名空间中声明的类,或者在该命名空间的内联命名空间集(7.3.1)(即,不仅仅是由using-declaration继承或引入),并且说明符应出现在包含先前声明的命名空间中。 在这种情况下,定义的class-head-name的nested-name- specifier 不应以 decltype-specifier开头。

于 2013-07-20T10:22:37.453 回答
-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;
};
于 2013-07-20T03:42:16.293 回答