[英]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 language-lawyer , I'm attempting a non-lawyer answer.由于您没有包括language-lawyer ,我正在尝试一个非律师的答案。
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.