C++ 使用模板时得到“不能出现在常量表达式中”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3984361/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
got "cannot appear in a constant-expression" when using template
提问by camino
template < int >
class CAT
{};
int main()
{
int i=10;
CAT<(const int)i> cat;
return 0; //here I got error: ‘i' cannot appear in a constant-expression
}
even
甚至
int i=10;
const int j=i;
CAT<j> cat; //this still can not work
but I have convert i to const int ,why compiler still report error ?
my platform is ubuntu,gcc version 4.4.3
但是我已经将 i 转换为 const int ,为什么编译器仍然报错?
我的平台是 ubuntu,gcc 版本 4.4.3
Thanks,
谢谢,
==============
==============
Thanks all for your input, but in some cases,I need a non-const variable ,
感谢大家的投入,但在某些情况下,我需要一个非常量变量,
for example:
例如:
//alloperations.h
enum OPERATIONS
{
GETPAGE_FROM_WEBSITE1,
GETPAGE_FROM_WEBSITE2,
....
};
template< OPERATIONS op >
class CHandlerPara
{
static string parameters1;
static string parameters2;
....
static void resultHandler();
};
//for different operations,we need a different parameter, to achieve this
//we specified parameters inside CHandler, for example
template<>
string CHandlerPara< GETPAGE_FROM_WEBSITE1 >::parameters1("&userid=?&info=?..")
template<>
string CHandlerPara< GETPAGE_FROM_WEBSITE1 >::parameters2("...")
other module will using this template to get corresponding parameter
and maybe specilize the resultHandler function for a special behavior
其他模块将使用此模板获取相应的参数,
并可能为特殊行为指定 resultHandler 函数
回答by James McNellis
A non-type template argument needs to be a compile-time constant. Casting an int
to a const int
does not make it a compile-time constant. You either need to use 10
directly:
非类型模板参数需要是编译时常量。将 an 转换int
为 aconst int
不会使其成为编译时常量。您要么需要10
直接使用:
CAT<10> cat;
or make i
a const int
:
或做i
一个const int
:
const int i = 10;
CAT<i> cat;
回答by Tony Delroy
It's important to understand what templates are: they're code that's reinstantiated for each combination of specific template types or values.
了解什么是模板很重要:它们是针对特定模板类型或值的每种组合重新实例化的代码。
void f(const int j) { CAT<j> cat; }
This is asking f
to create a different type of CAT<>
each time it runs, but templates must be resolved at compile time. Conceptually, the compiler might cope if you only ever called f()
with values it could work out at compile time, but if you're planning to that then you can simply write:
这要求f
在CAT<>
每次运行时创建不同的类型,但必须在编译时解析模板。从概念上讲,如果您只f()
使用它可以在编译时计算出的值进行调用,编译器可能会应付,但如果您打算这样做,那么您可以简单地编写:
template <int N>
void f() { CAT<N> cat; }
This willgenerate multiple f()
functions that create custom CAT<> instantiations.
这将生成多个f()
创建自定义 CAT<> 实例化的函数。
The C++ Standard doesn't even ask the compiler to tentatively accept the void f(const int j)
version - it would just be dubious baggage hanging around waiting to fail when somebody went to use it with a value determined at run time. People looking at the interface without looking over the entire implementation would expect f()
to be callable with such run-time values - e.g. f(atoi(argv[2]))
. Or, they might put for (int i = 0; i < 100000; ++i) f(i)
. If f()
takes an int
at run-time, and say gives it to CAT
as a constructor argument (i.e. as a run-time parameter rather than a template parameter) then that's fine and dandy, but if the compiler had to instantiate 100,000 versions of f()
each specialising CAT<>
s with successive values of i/N
the executable program size could become huge (optimisation - if enabled - may mitigate that).
C++ 标准甚至不要求编译器暂时接受该void f(const int j)
版本——当有人使用运行时确定的值使用它时,它只是等待失败的可疑包袱。在不查看整个实现的情况下查看接口的人们希望f()
可以使用此类运行时值调用 - 例如f(atoi(argv[2]))
. 或者,他们可能会将for (int i = 0; i < 100000; ++i) f(i)
. 如果在运行时f()
采用 an int
,并 say 将其CAT
作为构造函数参数(即作为运行时参数而不是模板参数)提供,那么这很好,但如果编译器必须实例化f()
每个专用CAT<>
s 的100,000 个版本具有连续值i/N
可执行程序的大小可能会变得很大(优化 - 如果启用 - 可以减轻这种情况)。