C++ 的要求是什么? 模板参数?
如果您在 C++ 中使用采用整数值作为参数的模板,则对用作参数的整数变量是否有与在函数调用中用作参数时不同的要求?
这是此处问题的后续 . 我特别想解决函数或模板声明为“extern const int”的 WRT 变量是否存在差异?
我可以看到,对于某些模板情况,在编译时需要参数值。 这总是正确的吗? 有没有一种方法可以指定(也许仅针对参数值的某些用途)在运行时使用该值?
If you are using a template in C++ that takes an integer value as a parameter, are there any requirements on an integer variable used as the parameter that are different than if the variable was used as a parameter in a function call?
This is a follow-up to question here . I specifically want to address if there is a difference WRT variables declared as "extern const int" for functions or templates?
I can see that for some template cases the parameter value would be needed at compile time. Is this always true? Is there a way to specify, maybe for only certain uses of the parameter value, that the value be used at runtime?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
以下内容来自标准。
14.3.2.1:
5.19.1:
关于您之前的帖子,我相信“const 变量...初始化与...”部分的本质(我认为外部初始化并不重要)。
The following is from the standard.
14.3.2.1:
5.19.1:
With respect to your previous post I believe the essence in the part "const variables ... initialised with ..." (and I don't think initialised externally counts).
它必须是一个整型常量表达式。
5.19
的标准文档对此进行了解释:请注意,“积分”是“整数”的另一个术语,但与“int”不同。 例如,“char”具有整数/整数类型,但显然不是 int 类型。 具体来说,以下内容是允许的
10 或 10L 或类似的值
enum { THIS, OR, THAT };
int const this_one = 10;
sizeof(char)
的任何一个都可以用作具有相应类型的整型类型的参数的模板参数。 但仍然应用一些转换。 因此,如果它需要一个 int 并且您传递一个 char,它会自动将 char 提升为 int。 如果您提供一个枚举器并且它需要一个 int,则相同。
因此,根据这些规则,如果您有
And 它没有看到使用整型常量表达式初始化该常量的定义,则它不能用作模板参数。 但当然,它可以用作函数参数。 这些不需要在编译时知道,因为它们不是类型的一部分。 当您命名模板特化时,您使用的参数就成为类型的一部分:
请注意,还有其他方法可以将
SomeName
作为参数传递。 然而,所有这些都不能被整数模板参数接受。 您可以通过引用参数接受上面的内容,例如它会接受上面的
SomeName
。 现在,选择的不是一个值,而是整个程序中唯一的特定位置(因为变量具有extern
链接)。It has to be a integral constant expression. That's explained by the Standard document at
5.19
:Note that "integral" is another term for "integer", but is not the same as "int". "char" for example has integer/integral type, but is not the int type, obviously. So concretely, the following is allowed
10 or 10L or anything like that
enum { THIS, OR, THAT };
int const this_one = 10;
sizeof(char)
Any of those can be used as a template argument for a parameter that has an integral type of the corresponding type. Some conversions are still applied though. So if it wants an int and you pass a char, it automatically promotes the char to the int. Same if you provide an enumerator and it wants an int.
So by those rules, if you have
And it does not see a definition which initializes that constant with a integral constant expression, it can't be used as a template argument. But it can be used as a function argument, of course. Those don't need to be known at compile time because those are not part of a type. The moment you name a template specialization, the arguments you used become part of the type:
Note that there are other ways to pass
SomeName
as an argument. However, all of which can not be accepted by an integer template parameter. You can accept the above by a reference parameter, for exampleAnd it would accept the
SomeName
of above. Now, rather than a value, a particular location that is unique across the whole program (as the variable hasextern
linkage) has been chosen.编译时总是需要 int 的值。
由于每个模板实例化都是一段单独的编译代码(即使对于整数模板参数也是如此),因此整数在编译时需要可用(并且必须保证永远不会更改)。
这也是为什么当您要使用大量唯一值时最好不要使用整数模板参数 - 您很快就会得到一个巨大的可执行文件。
It is always the case that the value of the int is needed at compile time.
Since each template instantiation is a separate piece of compiled code (even for integer template paramaters) that integer needs to be available when compiled (and it must be guaranteed to never change).
This is also why it's a good idea to not use integer template parameters when you are going to be using a large number of unique values - you can quickly end up with a huge executable file.