可以将静态成员变量声明为“内联”吗?

编程入门 行业动态 更新时间:2024-10-25 15:21:58
本文介绍了可以将静态成员变量声明为“内联”吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

众所周知,关键字内联有点误导,因为它的意思在实践中发生了变化。在大多数现代编译器中,它已经完全失去了如果可能的话,编译器内联 函数的暗示的含义。 (因为如果编译器具有在实例化点可用的函数 定义,它将估计 是否内联它,如果它估计它将是有益的, ,无论关键字''inline''是否出现在 函数定义中,都是如此。 实际上,关键字内联是指关键字实际上是一个链接器命令,而不是一个 编译器命令。它告诉链接器如果它在多个目标文件中找到该函数的实例化 ,它应该只使用 中的一个并丢弃其余的。 另外我们知道,模板 类的模板函数和成员函数是隐含的内联:如果它们被实例化为超过 一个编译单元(而不是内联),链接器在链接时只使用一个 实例化并丢弃其余部分。 有多少C ++程序员可能没有意识到,这种隐含的模板类成员的内联扩展到静态成员变量为 。换句话说,如果你这样做: //模板类头文件 // ------------- ------------------------------- template< typename T> class SomeClass { static int memberVariable; ... }; 模板< typename T> int SomeClass< T> :: memberVariable = 1; // -------- ------------------------------------ 和这个header用于多个编译单元,静态 成员变量也将在所有那些编译单元中实例化,但这不会导致链接器错误。链接器很好地使用只使用其中一个并丢弃其余部分。实际上,静态成员 变量已被声明为内联。 这不仅是模板类的一个很好的功能,而且是必须的。 /> 如果没有这个属性,就不可能在模板类中使用静态成员 变量,因为它不可能只在一个地方实例化(如果模板类用于 多个编译单元)。 所以我的问题是:为什么不能定期的静态成员变量 类被声明为inline,就像模板类一样? 编译器显然对此有支持,因为他们必须为 $ b $做这件事b模板类。但是,对于常规类的静态成员来说,似乎C ++标准不支持 。或者有没有一种方式我不知道?

解决方案

9月2日,12:26 am,Juha Nieminen< nos ... @ thanks.invalidwrote:

我们知道,关键字inline有点误导,因为 它的含义在实践中发生了变化。在大多数现代编译器中,它已经完全失去了编译器的暗示的意思 如果可能的话,内联函数 (因为如果编译器 具有在实例化时可用的函数定义 点,它将估计是否内联它,并且这样做 如果它估计它将是有益的,完全无论关键字''inline''是否出现在函数 定义中是否有b / b)。

除非编译器可以合理地确定比你更好的估算,否则我称之为bug,或者最差的质量 的实施。除非在非常有限的情况下,否则只有极少数编译器可以使用 。

事实上,关键字inline实际上是一个链接器命令, 不是编译器命令。

这不是一个命令,它是一个函数说明符,它在 中某种方式有点像存储类说明符。它是该语言的一部分 ,并且具有与 语言相关的特定语义(它使多个定义合法,只要 他们有不同的来源)。它也有一个意图,而且它是一个糟糕的编译器,它忽略了这个意图(除非,正如我所说, 确定它可以做得更好)。

它告诉链接器,如果它在多个目标文件中找到该 函数的实例,它应该只使用一个 他们并丢弃其余的。

不是。这是某些实现的一个方面,但它不是基本的b 。 (并且编译器可以使用非内联 函数执行此操作,如果需要的话。)

另外我们知道,模板函数和成员函数 模板类隐式内联:

不,他们不是,虽然他们也可以是多重定义的(当然,你要忘记导出的是)。

如果它们在多个编译单元中实例化 (并且没有内联),链接器在链接时只使用一个实例化 并丢弃其余部分。

再次,实现已定义。我使用的编译器没有任何模板函数直到链接时才实例化。 只有一次。

许多C ++程序员可能没有意识到,这个 隐式内联模板类成员也扩展到静态 成员变量。换句话说,如果你这样做:

//模板类头文件 // ----- --------------------------------------- template< typename T> class SomeClass { static int memberVariable; ... };

template< typename T> int SomeClass< T> :: memberVariable = 1; // --------------------------------------------

并且此标头用于多个编译单元, 静态成员变量也将在所有这些中实例化 编译单元,但这不会导致链接器错误。

再次,这是实现这一目标的一种方式(不是最好的,但可能是最广泛的b $ b)。按标准来说肯定不需要 。

链接器很好地只使用其中一个并丢弃 休息。实际上,静态成员变量已经声明为内联。

这不仅是模板类的一个很好的功能,而且必须是 。如果没有这个属性,就不可能在模板类中使用 静态成员变量,因为它只能在一个地方实例化(如果 模板类用于多个编译单元)。

所以我的问题是:为什么不能静态成员变量 常规类被声明为inline ,就像 模板类的那些?

因为内联说明符指示实现 ,内联替换函数体在 调用优先于通常的函数调用机制。 这显然对变量没有意义。并且虽然执行此内联 替换不需要 实现,但意图明确表达,并且它将是 a如果没有 非常好的理由不这样做,那么执行效果很差。

编译器显然有支持这是因为他们必须 为模板类做。但是,看似C ++ 标准不支持常规 类的静态成员。还是有一种我不知道的方式?

使课程成为模板:-)。 说真的,你为什么要这样做? - James Kanze(GABI软件)电子邮件:ja ********* @ gmail Conseils更多信息,请联系我们b $ b beratung in objektorientierter Datenverarbeitung 9placeSémard,78210 St.-Cyr-l''cocole,France,+ 33(0)1 30 23 00 34

James Kanze写道: [对待内联 as定义被内联到界面中]

说真的,你为什么要这样做?

只有头文件的库实现(带全局变量)将是一个 应用程序。 2 O 3周一,2008年9月1日22:26:08 +0000 ??? Juha Nieminen ?????°???

如我们所知,关键字直列"有点误导,因为它的含义 在实践中发生了变化。在大多数现代编译器中,它已经完全失去了b * b的含义,即如果 可能则编译器内联函数的提示。 (因为如果编译器在实例化点具有可用的函数定义 ,它将估计是否内联它, 并且如果它估计它将是有益,完全无论 关键字''inline''是否出现在函数定义中,或者 不是)。 实际上,关键字内联是指关键字实际上是一个链接器命令,而不是一个 编译器命令。它告诉链接器如果它在多个目标文件中找到该函数的实例化 ,它应该只使用 中的一个并丢弃其余的。 另外我们知道,模板 类的模板函数和成员函数是隐含的内联:如果它们被实例化为超过 一个编译单元(而不是内联),链接器在链接时只使用一个 实例化并丢弃其余部分。 有多少C ++程序员可能没有意识到,这种隐含的模板类成员的内联扩展到静态成员变量为 。换句话说,如果你这样做: //模板类头文件 // ------------- ------------------------------- template< typename T> class SomeClass { static int memberVariable; ... }; template< typename T> int SomeClass< T> :: memberVariable = 1; // ---------------------------------------- ---- 并且此标头用于多个编译单元,静态 成员变量也将在所有这些编译中实例化 单位,但这不会导致链接器错误。链接器很好地使用只使用其中一个并丢弃其余部分。实际上,静态成员 变量已被声明为内联。 这不仅是模板类的一个很好的功能,而且是必须的。 /> 如果没有这个属性,就不可能在模板类中使用静态成员 变量,因为它不可能只在一个地方实例化(如果模板类用于 多个编译单元)。 所以我的问题是:为什么不能定期的静态成员变量 类被声明为inline,就像模板类一样? 编译器显然对此有支持,因为他们必须为 $ b $做这件事b模板类。但是,对于常规类的静态成员来说,似乎C ++标准不支持 。还是有一种方式,我不知道吗?

您在模板中声明的那个不是内联的,即使它是在听众中 文件。 每当你使用 SomeClass< type>时,模板将被提取到常规类。不同的类型将被提取到不同的班级。 BTW:我只听说过内联函数,但没有内联变量。 - cch @ srdgame

As we know, the keyword "inline" is a bit misleading because its meaning has changed in practice. In most modern compilers it has completely lost its meaning of "a hint for the compiler to inline the function if possible" (because if the compiler has the function definition available at an instantiation point, it will estimate whether to inline it or not, and do so if it estimates it would be beneficial, completely regardless of whether the keyword ''inline'' appears in the function definition or not). In fact, the keyword "inline" is in practice a linker command, not a compiler command. It tells the linker that if it finds an instantiation of that function in more than one object file, it should use only one of them and discard the rest. Also as we know, template functions and member functions of template classes are implicitly "inline": If they are instantiated in more than one compilation unit (and not inlined), the linker will use only one instantiation when linking and discard the rest. What many C++ programmers might not realize is that this implicit inlining of template class members extends to static member variables as well. In other words, if you do this: // Template class header file // -------------------------------------------- template<typename T> class SomeClass { static int memberVariable; ... }; template<typename T> int SomeClass<T>::memberVariable = 1; // -------------------------------------------- and this header is used in more than one compilation unit, the static member variable will also be instantiated in all those compilation units, but this will not cause a linker error. The linker will nicely use only one of them and discard the rest. Effectively the static member variable has been declared "inline". This is not only a nice feature of template classes, but a must. Without this property it would be impossible to have static member variables in template classes because it would be impossible to instantiate them in only one place (if the template class is used in more than one compilation unit). So my question is: Why can''t static member variables of regular classes be declared "inline", like the ones of template classes? Compilers clearly have the support for this because they must do it for template classes. However, seemingly the C++ standard does not support this for static members of regular classes. Or is there a way that I don''t know of?

解决方案

On Sep 2, 12:26 am, Juha Nieminen <nos...@thanks.invalidwrote:

As we know, the keyword "inline" is a bit misleading because its meaning has changed in practice. In most modern compilers it has completely lost its meaning of "a hint for the compiler to inline the function if possible" (because if the compiler has the function definition available at an instantiation point, it will estimate whether to inline it or not, and do so if it estimates it would be beneficial, completely regardless of whether the keyword ''inline'' appears in the function definition or not).

Unless the compiler can be reasonably sure of making a better estimate than you, I''d call this a bug, or at least poor quality of implementation. And only a very few compilers are capable of this except in very limited cases.

In fact, the keyword "inline" is in practice a linker command, not a compiler command.

It''s not a command, it''s a "function specifier", which is in some ways a bit like a "storage class specifier". It''s a part of the language, and has a specific semantic associated with the language (it makes multiple definitions legal, provided that they are in different sources). It also has an "intent", and it is a poor compiler which ignores this intent (unless, as I said, it is certain that it can do better).

It tells the linker that if it finds an instantiation of that function in more than one object file, it should use only one of them and discard the rest.

No. That''s one aspect of some implementations, but it''s not fundamental. (And a compiler could do this with non-inline functions as well, if it wanted to.)

Also as we know, template functions and member functions of template classes are implicitly "inline":

No they''re not, although they can also be multiply defined (and you''re forgetting export, of course).

If they are instantiated in more than one compilation unit (and not inlined), the linker will use only one instantiation when linking and discard the rest.

Again, implementation defined. I''ve used compilers that didn''t instantiate any of the template functions until link time, and then only once.

What many C++ programmers might not realize is that this implicit inlining of template class members extends to static member variables as well. In other words, if you do this:

// Template class header file // -------------------------------------------- template<typename T> class SomeClass { static int memberVariable; ... };

template<typename T> int SomeClass<T>::memberVariable = 1; // --------------------------------------------

and this header is used in more than one compilation unit, the static member variable will also be instantiated in all those compilation units, but this will not cause a linker error.

Again, that''s one way (not the best, but probably the most widespread) of implementing this. It''s certainly not required by the standard.

The linker will nicely use only one of them and discard the rest. Effectively the static member variable has been declared "inline".

This is not only a nice feature of template classes, but a must. Without this property it would be impossible to have static member variables in template classes because it would be impossible to instantiate them in only one place (if the template class is used in more than one compilation unit).

So my question is: Why can''t static member variables of regular classes be declared "inline", like the ones of template classes?

Because "the inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism." Which obviously doesn''t make sense for variables. And "while an implementation is not required to perform this inline substitution", the intent is clearly expressed, and it would be a very poor implementation which didn''t perform it without a very good reason for not doing so.

Compilers clearly have the support for this because they must do it for template classes. However, seemingly the C++ standard does not support this for static members of regular classes. Or is there a way that I don''t know of?

Make the class a template:-). Seriously, why do you want to do it? -- James Kanze (GABI Software) email:ja*********@gmail Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l''école, France, +33 (0)1 30 23 00 34

James Kanze wrote: [treat "inline" as "the definition is inlined into the interface"]

Seriously, why do you want to do it?

Header-only implementations of libraries (with globals) would be an application.

?o? Mon, 01 Sep 2008 22:26:08 +0000???Juha Nieminen?????°???

As we know, the keyword "inline" is a bit misleading because its meaning has changed in practice. In most modern compilers it has completely lost its meaning of "a hint for the compiler to inline the function if possible" (because if the compiler has the function definition available at an instantiation point, it will estimate whether to inline it or not, and do so if it estimates it would be beneficial, completely regardless of whether the keyword ''inline'' appears in the function definition or not). In fact, the keyword "inline" is in practice a linker command, not a compiler command. It tells the linker that if it finds an instantiation of that function in more than one object file, it should use only one of them and discard the rest. Also as we know, template functions and member functions of template classes are implicitly "inline": If they are instantiated in more than one compilation unit (and not inlined), the linker will use only one instantiation when linking and discard the rest. What many C++ programmers might not realize is that this implicit inlining of template class members extends to static member variables as well. In other words, if you do this: // Template class header file // -------------------------------------------- template<typename T> class SomeClass { static int memberVariable; ... }; template<typename T> int SomeClass<T>::memberVariable = 1; // -------------------------------------------- and this header is used in more than one compilation unit, the static member variable will also be instantiated in all those compilation units, but this will not cause a linker error. The linker will nicely use only one of them and discard the rest. Effectively the static member variable has been declared "inline". This is not only a nice feature of template classes, but a must. Without this property it would be impossible to have static member variables in template classes because it would be impossible to instantiate them in only one place (if the template class is used in more than one compilation unit). So my question is: Why can''t static member variables of regular classes be declared "inline", like the ones of template classes? Compilers clearly have the support for this because they must do it for template classes. However, seemingly the C++ standard does not support this for static members of regular classes. Or is there a way that I don''t know of?

The one you decalared in template is not inline, even it is in hearder file. The template will be extracted to regular classes whenever you use SomeClass<type>. Different "type" will be extracted to different class. BTW: I only heard about inline function, but not inline variables. -- cch@srdgame

更多推荐

可以将静态成员变量声明为“内联”吗?

本文发布于:2023-11-14 03:04:07,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1586039.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:内联   变量   静态   声明   成员

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!