问题描述
众所周知,关键字内联有点误导,因为它的意思在实践中发生了变化。在大多数现代编译器中,它已经完全失去了如果可能的话,编译器内联
函数的暗示的含义。 (因为如果编译器具有在实例化点可用的函数
定义,它将估计
是否内联它,如果它估计它将是有益的,
,无论关键字''inline''是否出现在
函数定义中,都是如此。
实际上,关键字内联是指关键字实际上是一个链接器命令,而不是一个
编译器命令。它告诉链接器如果它在多个目标文件中找到该函数的实例化
,它应该只使用
中的一个并丢弃其余的。
另外我们知道,模板
类的模板函数和成员函数是隐含的内联:如果它们被实例化为超过
一个编译单元(而不是内联),链接器在链接时只使用一个
实例化并丢弃其余部分。
有多少C ++程序员可能没有意识到,这种隐含的模板类成员的内联扩展到静态成员变量为
。换句话说,如果你这样做:
//模板类头文件
// ------------- -------------------------------
template< typename T>
class SomeClass
{
static int memberVariable;
...
};
模板< typename T>
int SomeClass< T> :: memberVariable = 1;
// -------- ------------------------------------
和这个header用于多个编译单元,静态
成员变量也将在所有那些编译单元中实例化,但这不会导致链接器错误。链接器很好地使用
只使用其中一个并丢弃其余部分。实际上,静态成员
变量已被声明为内联。
这不仅是模板类的一个很好的功能,而且是必须的。 />
如果没有这个属性,就不可能在模板类中使用静态成员
变量,因为它不可能只在一个地方实例化
(如果模板类用于
多个编译单元)。
所以我的问题是:为什么不能定期的静态成员变量
类被声明为inline,就像模板类一样?
编译器显然对此有支持,因为他们必须为
$ b $做这件事b模板类。但是,对于常规类的静态成员来说,似乎C ++标准不支持
。或者有没有一种方式我不知道?
除非编译器可以合理地确定比你更好的估算
,否则我称之为bug,或者最差的质量
的实施。除非在非常有限的情况下,否则只有极少数编译器可以使用
。
这不是一个命令,它是一个函数说明符,它在
中某种方式有点像存储类说明符。它是该语言的一部分
,并且具有与
语言相关的特定语义(它使多个定义合法,只要
他们有不同的来源)。它也有一个意图,而且它是一个糟糕的编译器,它忽略了这个意图(除非,正如我所说,
确定它可以做得更好)。
不是。这是某些实现的一个方面,但它不是基本的b
。 (并且编译器可以使用非内联
函数执行此操作,如果需要的话。)
不,他们不是,虽然他们也可以是多重定义的(当然,你要忘记导出的是
)。
再次,实现已定义。我使用的编译器没有任何模板函数直到链接时才实例化。
只有一次。
再次,这是实现这一目标的一种方式(不是最好的,但可能是最广泛的b $ b)。按标准来说肯定不需要
。
因为内联说明符指示实现
,内联替换函数体在
调用优先于通常的函数调用机制。
这显然对变量没有意义。并且虽然执行此内联
替换不需要
实现,但意图明确表达,并且它将是
a如果没有
非常好的理由不这样做,那么执行效果很差。
使课程成为模板:-)。
说真的,你为什么要这样做?
-
James Kanze(GABI软件)电子邮件:ja ********* @ gmail.com
Conseils更多信息,请联系我们b $ b beratung in objektorientierter Datenverarbeitung
9placeSémard,78210 St.-Cyr-l''cocole,France,+ 33(0)1 30 23 00 34
只有头文件的库实现(带全局变量)将是一个
应用程序。
您在模板中声明的那个不是内联的,即使它是在听众中
文件。
每当你使用
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?
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.
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).
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.)
No they''re not, although they can also be multiply defined (and
you''re forgetting export, of course).
Again, implementation defined. I''ve used compilers that didn''t
instantiate any of the template functions until link time, and
then only once.
Again, that''s one way (not the best, but probably the most
widespread) of implementing this. It''s certainly not required
by the standard.
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.
Make the class a template:-).
Seriously, why do you want to do it?
--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Header-only implementations of libraries (with globals) would be an
application.
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
这篇关于可以将静态成员变量声明为“内联”吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!