移动语义:从"类型&&"到"类型"的转换无效。模板:将未知参数传递给重载函数

Move semantics: invalid conversion from `type&&` to `type`. Templates: passing unknown arguments to overloaded functions

本文关键字:类型 未知 参数传递 函数 模板 重载 转换 语义 无效 移动      更新时间:2023-10-16

故事如下:有一个固定类型的内存池Pool,用于存储某种类型T的元素。标题中列出的两个问题都是在制作构造新元素并将其添加到池中的alloc()函数时遇到的:

template <class T, size_t qty, class Alloc = allocator<T>>
class Pool {
    array <T*, qty> cells; // Pointers to pre-allocated memory
    ...
public:
    T& alloc (...) {   // [2] It is unknown what parameters T's constructor may take
        T&& tmp (...); // [2] But I need them to be passed as they are
        size_t cellNo = findEmptyCell(); // Returns the number of the cell
        *cells[cellNo] = tmp; // Placing the new object into the pool
                              // [1] "invalid conversion from 'int&& (*)(...)' to 'int'" when T is int
        isEmpty[cellNo] = false; // Marking the cell as occupied
        return *cells[cellNo];
    }
}

那么,1)在这种情况下如何避免不必要的对象复制?
2)有没有办法将任意参数传递给构造函数?

您正在寻找带有可变参数函数模板的"完美转发":

template <class... Args>
T& alloc(Args&&... args) { 
    size_t cellNo = findEmptyCell();
    *cells[cellNo] = T(std::forward<Args>(args)...);
    isEmpty[cellNo] = false;
    return *cells[cellNo];
}

这将接受任意数量的参数,并将它们转发(复制为右值,移动为右值)到T构造函数中。然后,该临时对象将被移动到*cells[cellNo]中。