从模板参数类型

时间:2018-07-20 16:52:02

标签: c++ class templates memory new-operator

我希望能够创建一个T类型的新对象,如此代码段所示。

template<typename T, typename Arg1, typename Arg2>
void ManageDevice(T& device, Arg1 arg1, Arg2 arg2)
{
    auto newDevice = new T{ arg1, arg2 };
    // ... Perform more operations on newDevice
}

我目前正在使用这样的功能:

CertainClass* device;
ManageDevice(device, arg1, arg2);

编译器返回错误:无法从“初始化列表”转换为“ T *类”。

我也尝试过:

auto newDevice = new decltype(device){ arg1, arg2 };

并出现以下错误:

错误C2464'T *&'的类:无法使用'new'分配引用

因此,我删除了此引用:

using DeviceType = std::remove_reference<decltype(device)>::type;
auto newDevice = new DeviceType{ arg1, arg2 };

然后我再次收到第一条错误消息。

问题:

  1. 知道这是否合法吗?我该怎么做才能使它生效?
  2. 在理想的世界中,我想通过直接将指针传递给类而不是此类的实例来调用该函数,这可能吗?
  3. 这个叫什么名字?

2 个答案:

答案 0 :(得分:3)

您的事实参数和模板参数不匹配。模板写为

template<typename T>
void foo(T& t);

并用

调用
D* d;
foo(d);

模板中T的类型将为D*。现在,如果您尝试

x = new D*{'a', 'b', 'c'};

您将看到一个明显的编译错误,因为没有(伪)构造函数来构造带有这些参数的指针。

要实现目标,您应该使用

template<typename T, typename Arg1, typename Arg2>
void ManageDevice(T*& device, Arg1 arg1, Arg2 arg2)...

在这种情况下,当用

调用时
Device* device;
ManageDevice(device...);

模板中实际的T可以推论为Device

这是在假设您使用device作为输出参数的情况下编写的。如果我猜对了,那么更好的选择是实际返回值,而不是使用输出参数:

template<typename T, typename Arg1, typename Arg2>
T* ManageDevice(Arg1 arg1, Arg2 arg2) {
   ...
   return new_device;
}

然后,您可以将其称为

auto* device = ManageDevice<Device>(a, b);

在其上的同时,将T *替换为unique_ptr<T>,将new替换为std::make_unique

答案 1 :(得分:2)

应为ManageDevice(*device, arg1, arg2);,因此推论得出TCertainClass,以便构造格式调用new T{。或者,如果要传递指针(可能不是一个好主意),请使用std::remove_pointerT获取对象类型:

using DeviceType = typename ::std::remove_pointer<T>::type;