非类型模板参数

发布于 2024-10-21 04:53:45 字数 1491 浏览 2 评论 0原文

我在使用非类型(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

才能让你更想念 2024-10-28 04:53:45

因为非类型模板参数需要在编译时赋值。请记住,模板是一种编译时机制;最终的可执行文件中不存在模板。还要记住,函数和向函数传递参数是运行时机制。 run() 中的 j 参数的值直到程序实际运行并调用 run() 函数才知道,远远超过了编译阶段之后。

void run(const int j)
{
    // The compiler can't know what j is until the program actually runs!
    MyTemplate<j> b;
}

const int i = 3;
run(i);

这就是为什么编译器抱怨“'j'不能出现在常量表达式中”。

另一方面,这也很好,因为 i 的值在编译时是已知的。

const int i = 3;
// The compiler knows i has the value 3 at this point,
// so we can actually compile this.
MyTemplate<i> a;

您可以将编译时值传递给运行时构造,但反之则不行。

但是,您可以让您的 run() 函数接受非类型模板参数,就像您的 MyTemplate 模板类接受非类型模板参数一样:

template<int j>
void run()
{
    MyTemplate<j> b;
}

const int i = 3;
run<i>();

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 in run() will not be known until the program actually runs and invokes the run() function, well past after the compilation stage.

void run(const int j)
{
    // The compiler can't know what j is until the program actually runs!
    MyTemplate<j> b;
}

const int i = 3;
run(i);

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.

const int i = 3;
// The compiler knows i has the value 3 at this point,
// so we can actually compile this.
MyTemplate<i> a;

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 your MyTemplate template class accepts a non-type template parameter:

template<int j>
void run()
{
    MyTemplate<j> b;
}

const int i = 3;
run<i>();
番薯 2024-10-28 04:53:45

基本上,C++ 有两种常量:

const int a = 5;
MyTemplate<a> foo; // OK

const int b = rand();
MyTemplate<b> foo; // Not OK.

第一个示例是编译时常量。用 C++ 标准来说,它是一个积分常量表达式 (ICE)。第二个例子是运行时常量。它具有相同的 C++ 类型 (const int),但它不是 ICE。

您的函数 void run(const int j) 是一个运行时常量。您甚至可以传递用户输入。因此它不是一个有效的模板参数。

该规则的原因是编译器必须根据模板参数值生成代码。如果它没有编译时常量,它就不能这样做。

Basically, C++ has two kinds of constants:

const int a = 5;
MyTemplate<a> foo; // OK

const int b = rand();
MyTemplate<b> foo; // Not OK.

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.

青衫负雪 2024-10-28 04:53:45

因为 j 应该在编译时就知道。在你的例子中它不是。

Because j should be known at compile time. In your example it is not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文