gpt4 book ai didi

c++ - `extern` 带有和不带有参数列表的类模板实例的声明和后续定义

转载 作者:搜寻专家 更新时间:2023-10-31 01:28:16 26 4
gpt4 key购买 nike

考虑以下代码:

template <typename T = int> struct X {};
extern X foo;
X foo;

Live on gcc.godbolt.org

我希望它的格式正确,但 GCC、Clang 和 MSVC 拒绝它并显示以下错误消息:

GCC 8.2(使用 -std=c++17 -Wall -Wextra -pedantic-errors):

<source>:3:3: error: conflicting declaration 'X foo'
X foo;
^~~
<source>:2:10: note: previous declaration as 'X<int> foo'
extern X foo;
^~~

Clang 7.0.0(带有 -std=c++17 -Wall -Wextra -pedantic-errors):

<source>:2:10: error: declaration of variable 'foo' with deduced type 'X' requires an initializer
extern X foo;
^

MSVC Pre 2018(使用 /std:c++latest):

<source>(2): error C2641: cannot deduce template argument for 'X'
<source>(3): error C2133: 'foo': unknown size
<source>(3): error C2641: cannot deduce template argument for 'X'

现在是有趣的部分。

此片段被 Clang 接受但被 GCC 和 MSVC 拒绝:

extern X<> foo;
X foo;

此代码段被 GCC 接受但被 Clang 和 MSVC 拒绝:

extern X foo;
X<> foo;

这一个被所有三个编译器接受:

extern X<> foo;
X<> foo;

最后这个被 GCC 和 Clang 接受但被 MSVC 拒绝:

X foo;

这是怎么回事?这五个片段中哪一个是正确的?

最佳答案

clang 在您的所有五个片段中都是正确的。

extern X<> foo; // type: X<>
X foo; // CTAD => type: X<>

foo 只是 foo 的一个声明,随后以相同的类型重新声明,因此 gcc 和 MSVC 拒绝这种情况是错误的。

extern X foo; // invalid
X<> foo; // ok => type: X<>

gcc 在这里是错误的。 foo 不是定义,只是没有初始值设定项的声明,因此不是 initializing declaration。正如 CTAD 所要求的那样 ( [dcl.class.type.deduct] )。

extern X<> foo; // type: X<>
X<> foo; // type: X<>

这与 1) 类似,只是不需要 CTAD。由于第二个 foo 只是对 foo 的重新声明,并且同时定义了相同的类型,所以它是有效的。

X foo;

MSVC 在这里是错误的,该标准没有在全局范围内对 CTAD 施加任何限制。

总而言之,我们可以推断您的原始代码段格式错误,因为您对 undefined variable 使用 CTAD。

关于c++ - `extern` 带有和不带有参数列表的类模板实例的声明和后续定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52515350/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com