类中不允许使用不完整的类型,但类模板中允许使用不完整的类型

gflegar

以下是无效的代码:

struct foo {
    struct bar;
    bar x;        // error: field x has incomplete type
    struct bar{ int value{42}; };
};

int main() { return foo{}.x.value; }

这很清楚,因为foo::barfoo::x定义的位置被认为是不完整的

但是,似乎有一个“替代方法”使相同的类定义有效:

template <typename = void>
struct foo_impl {
    struct bar;
    bar x;        // no problems here
    struct bar{ int value{42}; };
};

using foo = foo_impl<>;

int main() { return foo{}.x.value; }

适用于所有主要编译器。我对此有三个问题:

  1. 这确实是有效的C ++代码,还是只是一些古怪的编译器?
  2. 如果它是有效的代码,那么C ++标准中是否有一段处理此异常?
  3. 如果它是有效的代码,为什么第一个版本(不带template)被认为无效?如果编译器可以找出第二个选项,那么我看不出为什么它不能找出第一个选项的原因。

如果我为以下内容添加明确的专业化void

template <typename = void>
struct foo_impl {};

template<>
struct foo_impl<void> {
    struct bar;
    bar x;        // error: field has incomplete type
    struct bar{ int value{42}; };
};

using foo = foo_impl<>;

int main() { return foo{}.x.value; } 

它再次无法编译

巴里

真正的答案可能是\\(())_ /,但由于模板具有魔力,目前可能尚可,但在其他一些核心问题解决方案之前,它可能显然不可行。

首先,主要的问题当然是[class.mem] / 14

非静态数据成员不应具有不完整的类型。

这就是为什么您的非模板示例格式错误的原因。但是,根据[temp.point] / 4

对于类模板专业化,类成员模板专业化或对类模板的类成员的专业化,如果该专业化是隐式实例化的,因为该专业化是从另一个模板专业化内部引用的,则如果引用该专业化的上下文取决于在模板参数上,并且如果未在封闭模板的实例化之前实例化专业化,则实例化点紧接在封闭模板的实例化点之前否则,此类专门化的实例化点紧接在引用该专门化的名称空间范围声明或定义之前。

这表明该foo_impl<void>::bar对象在之前 实例化foo_impl<void>,因此在bar实例化类型的非静态数据成员时就完成了该操作所以也许没关系。

但是,核心语言问题16262335处理的关于完整性和模板的问题不完全相同,但仍然非常相似,并且都指向希望使模板用例与非模板用例更加一致。

从整体上看,这意味着什么?我不确定。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C ++中不允许使用不完整的类型

交换程序中不允许使用不完整的类型

不允许使用不完整的类型:stringstream

C ++结构“不允许使用不完整的类型”

推力copy_if:不允许使用不完整的类型

无效使用不完整的类型“类”

使用头文件中定义的结构作为函数参数时,“不允许使用不完整类型”

c ++“不允许使用不完整的类型”错误访问类参考信息(带有前向声明的循环依赖)

在类模板的成员函数中使用不完整类型

模板类和“无效使用不完整类型”错误

引用不完整的类类型-C ++

为什么我们允许使用不完整类型的地址?

为什么允许使用不完整的枚举类?

从外部定义的类继承时,无效使用不完整类型类错误

如何使用不完整的类型

GCC元组“无效使用不完整类型”

类的前向声明/无效使用不完整的类型

为什么std :: vector在类定义中使用不完整的类型?

使用模板化类型和名称空间的“无效使用不完整类型”

const函数指针类型作为模板参数的“无效使用不完整类型”

在模板中使用不完整的類型

“不允许不完整的类型”类类型数组

无效使用不完整类型进行部分模板专业化C ++

使用不完整类型的函数模板的显式实例化

使用不完整类型的功能模板实例化

使用C ++ 11 std :: async在android ndk中无效使用不完整类型

取消引用不完整类型的指针

取消引用不完整类型的指针

取消引用不完整类型“ struct”的指针