模板与内存分配

发布于 2024-10-29 13:48:36 字数 287 浏览 1 评论 0原文

#include <iostream>

template<class T> T CreateArray(T a, int n)
{
    a = new T [n]; // mistake: double* = double**
    return a;
}

int main()
{
    double* a;
    int n = 5;
    a = CreateArray(a,n);
    return 0;
}

我可以使用模板和新分配内存吗?我的错误是什么?

#include <iostream>

template<class T> T CreateArray(T a, int n)
{
    a = new T [n]; // mistake: double* = double**
    return a;
}

int main()
{
    double* a;
    int n = 5;
    a = CreateArray(a,n);
    return 0;
}

can I allocate memory using a template and new? And what my mistake?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

凡尘雨 2024-11-05 13:48:36

你的代码有一些错误的地方。首先,您可以做类似您想要做的事情,但您应该编写如下内容:

template<class T> T* CreateArray(int n)
{
    T* a = new T [n];
    return a;
}

int main()
{
    double* a;
    int n = 5;
    a = CreateArray<double>(n);
    return 0;
}

请注意,您不必传递 a 数组(它将被复制到 >CreateArray,其更改在 main 内不可见)。另请注意,您定义了返回指针 T* 的模板,这正是 main() a 所期望的。

Your code has some wrong things. First, you can do something like what you're trying to do, but you should write something like this:

template<class T> T* CreateArray(int n)
{
    T* a = new T [n];
    return a;
}

int main()
{
    double* a;
    int n = 5;
    a = CreateArray<double>(n);
    return 0;
}

Note that you don't have to pass the a array (it will be copied inside CreateArray, and its changes won't be visible inside main). Note also that you define the template to returning a pointer T*, that is what main() a is expecting.

怀里藏娇 2024-11-05 13:48:36

因此其他人已经解释了为什么您的代码不起作用以及如何改进它。

现在我将展示如何仍然让以下代码进行编译并正常工作:

 double* a = CreateArray(5);
 int* b = CreateArray(7);

正如已经提到的,问题是 C++ 不会单独从返回类型推断模板参数。

您可以通过使上述函数返回一个简单的代理对象来规避此限制。代理对象只有一个操作:(隐式)转换为 T*。这是实际分配发生的地方。

因此,CreateArray 函数非常简单(并且不是模板):

CreateArrayProxy CreateArray(std::size_t num_elements) {
    return CreateArrayProxy(num_elements);
}

至于代理:

struct CreateArrayProxy {
    std::size_t num_elements;

    CreateArrayProxy(std::size_t num_elements) : num_elements(num_elements) { }

    template <typename T>
    operator T*() const {
        return new T[num_elements];
    }
};

简单如 π。

现在,您应该使用这段代码吗?不,可能不会。与直接分配相比,它没有提供真正的优势。但这是一个很有用的习语。

So others have explained why your code doesn’t work and how it can be improved.

Now I’ll show how you can still get the following code to compile – and to work properly:

 double* a = CreateArray(5);
 int* b = CreateArray(7);

The problem, as already mentioned, is that C++ does not infer template arguments from return types alone.

You can circumvent this limitation by making the above function return a simple proxy object. The proxy object has a single operation: an (implicit) conversion to T*. This is where the actual allocation happens.

The CreateArray function is therefore very simple (and not a template):

CreateArrayProxy CreateArray(std::size_t num_elements) {
    return CreateArrayProxy(num_elements);
}

As for the proxy:

struct CreateArrayProxy {
    std::size_t num_elements;

    CreateArrayProxy(std::size_t num_elements) : num_elements(num_elements) { }

    template <typename T>
    operator T*() const {
        return new T[num_elements];
    }
};

Easy as π.

Now, should you use this code? No, probably not. It offers no real advantage over direct allocation. But it’s a useful idiom to know.

滥情稳全场 2024-11-05 13:48:36

您想要接受指向要分配的类型的指针

template<class T> T* CreateArray(T* a, int n)
{
    a = new T [n];
    return a;
}

这应该可以解决问题。

You want to accept a pointer to the type you want to allocate:

template<class T> T* CreateArray(T* a, int n)
{
    a = new T [n];
    return a;
}

This should do the trick.

℉服软 2024-11-05 13:48:36

我更喜欢将空指针值保留为 NULL。

#include <iostream>

template<class T> bool CreateArray(T * &a, int n)
{
    if ( a != 0 )
      return false;
    a = new T [n];
    return true;
}

int main()
{
    double* a = 0;
    int n = 5;
    CreateArray(a,n);
    return 0;
}

vector 也可能是一个很好的解决方案。我认为这是更好的一种,因为你不会造成内存泄漏。

#include <vector>

int main()
{
    std::vector<double> a;
    int n = 5;
    a.resize(n);
    return 0;
}

I prefer to keep empty pointers value NULL.

#include <iostream>

template<class T> bool CreateArray(T * &a, int n)
{
    if ( a != 0 )
      return false;
    a = new T [n];
    return true;
}

int main()
{
    double* a = 0;
    int n = 5;
    CreateArray(a,n);
    return 0;
}

vector could be a good solution, too. I think it is better one, because you won't make memory leak(s).

#include <vector>

int main()
{
    std::vector<double> a;
    int n = 5;
    a.resize(n);
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文