gpt4 book ai didi

c++ - 在模板函数中使用未声明的变量是否合法?

转载 作者:IT老高 更新时间:2023-10-28 21:35:56 26 4
gpt4 key购买 nike

注意:原题大量使用宏,但本题已简化。

问题

// header.hpp
template <typename T>
void foo()
{
someBoolean = true ; // at this point "someBoolean" wasn't
} // declared

然后,它在以下来源中使用:

// source.cpp
#include "header.hpp"

static bool someBoolean = false ;

void bar()
{
foo<char>() ; // here, we call/instantiate the function
}

在某些编译器(Windows、以前的 Solaris)中它可以工作。而在当前启用 C++11 的 Solaris 编译器中,它会失败,说 someBoolean 未定义。

根据标准,模板化代码可以使用(我们希望!)稍后在源代码中声明的变量吗?

奖金问题

模板在一个头文件中定义,该头文件预计将包含在多个源中,每个源都有自己的 bool 变量,并实例化模板。

预计,在每个翻译单元中,模板都会影响该翻译单元的静态 bool 变量。

因此,预计在一种类型(例如“char”)上的模板的每个实例化都会影响不同的变量。

我们不是依赖未定义的行为吗?

最佳答案

这与两阶段查找有关。简短的版本是,任何 not 依赖于模板参数的名称(如 someBoolean 此处)将在模板定义时查找。这意味着 Solaris 编译器拒绝代码是正确的。 someBoolean 在定义模板之前没有定义。

确实依赖于模板参数的名称(例如,如果您编写了类似 T::someBoolean = true 之类的东西)将推迟到模板实例化时间 - 非常合理,因为它们的有效性不能在编译器知道 T 是什么之前确定。 MSVC 以没有正确实现这些两阶段语义而闻名(至少从历史上看),这就是您的代码在那里工作的原因。不过,这不是正确的 C++,也不是可移植的行为。

C++ 标准(可能是草案)(未知版本)的第 14.6 节:

If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition; the name is bound to the declaration (or declarations) found at that point and this binding is not affected by declarations that are visible at the point of instantiation.

(通过下面的@BenVoigt 评论)

关于c++ - 在模板函数中使用未声明的变量是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29541875/

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