非类型模板参数
我在使用非类型(int 变量)模板参数时遇到问题。
为什么我不能将常量 int 变量传递给函数并让函数实例化模板?
template<int size>
class MyTemplate
{
// do something with size
};
void run(const int j)
{
MyTemplate<j> b; // not fine
}
void main()
{
const int i = 3;
MyTemplate<i> a; // fine;
run(i); // not fine
}
不好:编译器说,错误:'j'不能出现在常量表达式中
- 编辑
这就是我最终得到的结果。 也许有人可能会使用它,有人可能会建议更好的方法。
enum PRE_SIZE
{
PRE_SIZE_256 = 256,
PRE_SIZE_512 = 512,
PRE_SIZE_1024 = 1024,
};
template<int size>
class SizedPool : public Singleton< SizedPool<size> >
{
public:
SizedPool()
: mPool(size)
{
}
void* Malloc()
{
return mPool.malloc();
}
void Free(void* memoryPtr)
{
mPool.free(memoryPtr);
}
private:
boost::pool<> mPool;
};
template<int size>
void* SizedPoolMalloc()
{
return SizedPool<size>::GetInstance()->Malloc();
}
template<int size>
void SizedPoolFree(void* memoryPtr)
{
SizedPool<size>::GetInstance()->Free(memoryPtr);
}
void* SizedPoolMalloc(int size)
{
if (size <= PRE_SIZE_256)
return SizedPoolMalloc<PRE_SIZE_256>();
else if (size <= PRE_SIZE_512)
return SizedPoolMalloc<PRE_SIZE_512>();
}
void toRun(const int j)
{
SizedPoolMalloc(j);
}
void Test17()
{
const int i = 3;
toRun(i);
}
I'm having trouble with nontype(int variable) template parameter.
Why can't I pass a constant int variable to a function and let the function instantiate the template?
template<int size>
class MyTemplate
{
// do something with size
};
void run(const int j)
{
MyTemplate<j> b; // not fine
}
void main()
{
const int i = 3;
MyTemplate<i> a; // fine;
run(i); // not fine
}
not fine : compiler says, error: 'j' cannot appear in constant-expression
- EDIT
This is what I ended up with.
Maybe someone might use it, someone might suggest better way.
enum PRE_SIZE
{
PRE_SIZE_256 = 256,
PRE_SIZE_512 = 512,
PRE_SIZE_1024 = 1024,
};
template<int size>
class SizedPool : public Singleton< SizedPool<size> >
{
public:
SizedPool()
: mPool(size)
{
}
void* Malloc()
{
return mPool.malloc();
}
void Free(void* memoryPtr)
{
mPool.free(memoryPtr);
}
private:
boost::pool<> mPool;
};
template<int size>
void* SizedPoolMalloc()
{
return SizedPool<size>::GetInstance()->Malloc();
}
template<int size>
void SizedPoolFree(void* memoryPtr)
{
SizedPool<size>::GetInstance()->Free(memoryPtr);
}
void* SizedPoolMalloc(int size)
{
if (size <= PRE_SIZE_256)
return SizedPoolMalloc<PRE_SIZE_256>();
else if (size <= PRE_SIZE_512)
return SizedPoolMalloc<PRE_SIZE_512>();
}
void toRun(const int j)
{
SizedPoolMalloc(j);
}
void Test17()
{
const int i = 3;
toRun(i);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因为非类型模板参数需要在编译时赋值。请记住,模板是一种编译时机制;最终的可执行文件中不存在模板。还要记住,函数和向函数传递参数是运行时机制。
run()
中的j
参数的值直到程序实际运行并调用run()
函数才知道,远远超过了编译阶段之后。这就是为什么编译器抱怨“'j'不能出现在常量表达式中”。
另一方面,这也很好,因为
i
的值在编译时是已知的。您可以将编译时值传递给运行时构造,但反之则不行。
但是,您可以让您的
run()
函数接受非类型模板参数,就像您的MyTemplate
模板类接受非类型模板参数一样:Because non-type template parameters require values at compile-time. Remember that templates are a compile-time mechanism; templates do not exist in the final executable. Also remember that functions and the passing of arguments to functions are runtime mechanisms. The value of the
j
parameter inrun()
will not be known until the program actually runs and invokes therun()
function, well past after the compilation stage.That's why the compiler complains says "'j' cannot appear in constant-expression".
On the other hand, this is fine because the value of
i
is known at compile-time.You can pass compile-time values to run-time constructs, but not the other way around.
However, you can have your
run()
function accept a non-type template parameter the same way yourMyTemplate
template class accepts a non-type template parameter:基本上,C++ 有两种常量:
第一个示例是编译时常量。用 C++ 标准来说,它是一个积分常量表达式 (ICE)。第二个例子是运行时常量。它具有相同的 C++ 类型 (
const int
),但它不是 ICE。您的函数
void run(const int j)
是一个运行时常量。您甚至可以传递用户输入。因此它不是一个有效的模板参数。该规则的原因是编译器必须根据模板参数值生成代码。如果它没有编译时常量,它就不能这样做。
Basically, C++ has two kinds of constants:
The first example is a compile-time constant. In C++ standard speak, it's an Integral Constant Expression (ICE). The second example is a run-time constant. It has the same C++ type (
const int
) but it's not an ICE.Your function
void run(const int j)
is a run-time constant. You could even pass in user input. Therefore it's not a valid template argument.The reason for the rule is that the compiler must generate code based on the template argument value. It can't do so if it doesn't have a compile-time constant.
因为 j 应该在编译时就知道。在你的例子中它不是。
Because j should be known at compile time. In your example it is not.