移动语义:从“type&&”到“type”的无效转换。模板:将未知参数传递给重载函数
Move semantics: invalid conversion from `type&&` to `type`. Templates: passing unknown arguments to overloaded functions
故事如下:有一个 fixed-type 内存池 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) 在这种情况下如何避免不必要的 object 复制?
以及 2) 有没有办法将任意参数传递给构造函数?
您正在寻找具有可变函数模板的"perfect forwarding":
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]
.
故事如下:有一个 fixed-type 内存池 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) 在这种情况下如何避免不必要的 object 复制?
以及 2) 有没有办法将任意参数传递给构造函数?
您正在寻找具有可变函数模板的"perfect forwarding":
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]
.