简体   繁体   English

using 声明是否在所有情况下都允许不完整的类型?

[英]Does the using declaration allow for incomplete types in all cases?

I'm a bit confused about the implications of the using declaration.我对using声明的含义有点困惑。 The keyword implies that a new type is merely declared.该关键字意味着仅声明了一个新类型。 This would allow for incomplete types.这将允许不完整的类型。 However, in some cases it is also a definition, no?但是,在某些情况下,它也是一个定义,不是吗? Compare the following code:比较以下代码:

#include <variant>
#include <iostream>

struct box;

using val = std::variant<std::monostate, box, int, char>;

struct box
{
    int a;
    long b;
    double c;
    
    box(std::initializer_list<val>) {
        
    }
};

int main()
{
    std::cout << sizeof(val) << std::endl;
}

In this case I'm defining val to be some instantiation of variant.在这种情况下,我将 val 定义为变体的一些实例化。 Is this undefined behaviour?这是未定义的行为吗? If the using-declaration is in fact a declaration and not a definition, incomplete types such as box would be allowed to instantiate the variant type.如果 using-declaration 实际上是声明而不是定义,则允许不完整的类型(例如 box)实例化变体类型。 However, if it is also a definition, it would be UB no?但是,如果它也是一个定义,那会是UB吗?

For the record, both gcc and clang both create "32" as output.作为记录,gcc 和 clang 都创建“32”作为输出。

Since you've not included , I'm attempting a non-lawyer answer.由于您没有包括 ,我正在尝试一个非律师的答案。

Why should that be UB?为什么应该是UB?

With a using delcaration, you're just providing a synonym for std::variant<whatever> .使用using声明,您只需提供std::variant<whatever>的同义词。 That doesn't require an instantiation of the object, nor of the class std::variant , pretty much like a function declaration with a parameter of that class doesn't require it:这不需要对象的实例化,也不需要std::variant类的实例化,就像带有该类参数的函数声明不需要它:

void f(val); // just fine

The problem would occur as soon as you give to that function a definition (if val is still incomplete because box is still incomplete):只要您给该函数一个定义,就会出现问题(如果val仍然不完整,因为box仍然不完整):

void f(val) {}

But it's enough just to change val to val& for allowing a definition,但是只需将val更改为val&以允许定义就足够了,

void f(val&) {}

because the compiler doesn't need to know anything else of val than its name.因为编译器不需要知道val除了它的名字之外的任何东西。


Furthermore, and here I'm really inventing, "incomplete type" means that some definition is lacking at the point it's needed, so I expect you should discover such an issue at compile/link time, and not by being hit by UB.此外,在这里我真的在发明,“不完整类型”意味着在需要的时候缺少一些定义,所以我希望你应该在编译/链接时发现这样的问题,而不是被 UB 击中。 As in, how can the compiler and linker even finish their job succesfully if a definition to do something wasn't found?例如,如果没有找到做某事的定义,编译器和链接器怎么能成功完成他们的工作?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么仅保证这些C ++标准库容器允许不完整的类型? - Why are only these C++ standard library containers guaranteed to allow incomplete types? 为什么std :: array的演绎指南不允许使用不同的类型? - Why deduction guide for std::array does not allow different types? 为什么包扩展允许约束依赖模板的类型而不是常规类型? - Why does pack expansion allow to constrain template-dependent types but not regular types? 不完整类型作为函数参数和返回值 - Incomplete types as function parameters and return values 使用构造函数的声明会损害访问说明符并且与其他类型的成员不一致 - Using declaration of constructors compromises access specifiers and isn't consistent with other types of members std :: map和std :: variant的不完整类型 - incomplete types with std::map and std::variant 允许隐式转换具有相同基础结构的类型 - Allow implicit casting for types with the same underlying structure 在类模板的成员函数中使用不完整类型 - Using incomplete type in a member function of a class template 有条件地提供 using 声明 - Conditionally provide a using declaration 使用声明和 function 默认 arguments - The using declaration and function default arguments
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM