【问题标题】:C++ Template function with dynamic variables具有动态变量的 C++ 模板函数
【发布时间】:2020-03-14 14:05:58
【问题描述】:

我正在寻找一个 -std=gnu++17(或 20,如果已经可用)的解决方案来处理对象和 malloc。我想有一个模板函数来用 malloc 分配内存并构造对象。对象本身可以是任何东西,所以它可能需要构造函数中的 10 个参数,或者不需要。我如何模板功能支持这个?思路应该类似于 printfs 变量参数列表,但是这里不是 print 的参数,而是变量,调用构造函数。

新的 c++ 标准有很多进展,但如果你不习惯它也会很混乱。是否有人真正了解这些 c++ 功能并且可以提供帮助?

本次讨论不应包括“如何分配内存和构造对象”。模板编码很有趣

template<typename T, typename... args>
T * malloc_and_construct()
{
    T* pobj = (T*)malloc(sizeof(T));
    if(pobj) new (pobj) T(args...);
    return pobj;
}
template<typename T>
void destruct_and_free(T* pobj)
{
    if(pobj) {
        pobj->~T();
        free(pobj);
    }
}

【问题讨论】:

  • 您是否考虑过使用newdelete
  • @HolyBlackCat 我知道这一点。不幸的是,我不能使用 new 和 delete,唯一的例外是要构建的新位置。只对模板功能感兴趣。仅将 malloc 函数视为演示代码。这个讨论不应该是关于如何在 C++ 中分配内存。
  • 您正在寻找parameter pack
  • @BlueTune 是的,我看到了这个,但我不明白。你有一个简单的例子让我学习吗?
  • 查看std::make_unique here 的实现,你可能想要类似的东西。

标签: c++ templates c++17 c++20


【解决方案1】:

这是你要找的吗?

template<typename TClass, typename ... TArgs>
TClass* malloc_and_construct(TArgs&& ... args)
{
    auto* ptr = malloc(sizeof(TClass));
    if (ptr == nullptr)
        return nullptr;
    return new (ptr) TClass { std::forward<TArgs>(args)... };
}

【讨论】:

  • 我在这里使用(...) 而不是{...},以与类似的标准功能保持一致,并避免意外行为,例如标准容器。
【解决方案2】:
// Example program
#include <iostream>
#include <string>
#include <cstdlib>

template<typename T, typename... Args>
T * malloc_and_construct(Args &&... args)
{
    T* pobj = (T*)malloc(sizeof(T));
    if(pobj) new (pobj) T(std::forward<Args>(args)...);
    return pobj;
}
template<typename T>
void destruct_and_free(T* pobj)
{
    if(pobj) {
        pobj->~T();
        free(pobj);
    }
}

struct A
{
    A(int a, int b) : a(a), b(b) { printf("A %d %d\n", a,b); }
    ~A() { printf("~A\n");  }
    private:
    int a;
    int b;
};

struct B
{
    B() { printf("B\n"); }
    ~B() { printf("~B\n"); }
};


int main()
{
    A * a = malloc_and_construct<A>(2, 3);
    B * b = malloc_and_construct<B>();

    destruct_and_free(a);
    destruct_and_free(b);

    return 0;
}

结果:

A 2 3 乙 〜一个 ~B

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 2010-11-02
    • 1970-01-01
    相关资源
    最近更新 更多