如果 T 具有显式构造函数,则无法使用 emplace new 将元素添加到容器 <T>
Can't add element into container<T> with emplace new if T has explicit constructor
我正在写一个固定大小的容器类型,放置位置是新的。
当我测试它时,我发现如果类型 T 具有显式构造函数,我的“emplace_back()”之类的函数将无法编译。
这是一个代码示例(缺少删除调用等):
#include <iostream>
template <typename T>
struct TestType
{
explicit TestType(T value) // removing explicit makes it a compileable code
{
std::cout << value << std::endl;
}
};
template <typename... Args>
void emplace(TestType<int>* buffer, Args&&... args)
{
// placement new // compile time error in this line
new (buffer) TestType<int>(std::forward<TestType<int>>(args)...);
}
int main()
{
TestType<int>* buffer;
buffer = (static_cast<TestType<int>*>(::operator new(sizeof(TestType<int>) * 10)));
emplace(buffer, 5);
return 0;
}
错误是:
" 在 'void emplace(TestType*, Args&& ...) [with Args = {int}]' 的实例化中:
24:22: 从这里需要
16:64: 错误: 没有匹配函数来调用 'forward(int&)'"
Whosebug 上有一些类似的问题,但这些问题大多是关于 std::map,可能我的问题有所不同。 (如果不是,我仍然不明白发生了什么。)
如果(例如)std::vector emplace_back() 适用于任何带有显式构造函数的 T 类型,为什么它不适用于我的容器类型?
这编译得很好:
#include <iostream>
#include <vector>
template <typename T>
struct TestType
{
explicit TestType(T value)
{}
};
int main()
{
std::vector<TestType<int>> vector;
vector.emplace_back(5);
return 0;
}
感谢您的帮助!
您将 TestType<int>
指定为 std::forward
的模板参数作为 std::forward<TestType<int>>(args)...
,这意味着您将参数转发为 TestType<int>
。传递的参数试图隐式转换为 TestType<int>
,这不起作用,因为转换构造函数被标记为 explicit
.
您应该将 Args
指定为 std::forward
的模板参数,即将参数转发为:
template <typename... Args>
void emplace(TestType<int>* buffer, Args&&... args)
{
// placement new
new (buffer) TestType<int>(std::forward<Args>(args)...);
// ^^^^
}
我正在写一个固定大小的容器类型,放置位置是新的。 当我测试它时,我发现如果类型 T 具有显式构造函数,我的“emplace_back()”之类的函数将无法编译。
这是一个代码示例(缺少删除调用等):
#include <iostream>
template <typename T>
struct TestType
{
explicit TestType(T value) // removing explicit makes it a compileable code
{
std::cout << value << std::endl;
}
};
template <typename... Args>
void emplace(TestType<int>* buffer, Args&&... args)
{
// placement new // compile time error in this line
new (buffer) TestType<int>(std::forward<TestType<int>>(args)...);
}
int main()
{
TestType<int>* buffer;
buffer = (static_cast<TestType<int>*>(::operator new(sizeof(TestType<int>) * 10)));
emplace(buffer, 5);
return 0;
}
错误是: " 在 'void emplace(TestType*, Args&& ...) [with Args = {int}]' 的实例化中: 24:22: 从这里需要 16:64: 错误: 没有匹配函数来调用 'forward(int&)'"
Whosebug 上有一些类似的问题,但这些问题大多是关于 std::map,可能我的问题有所不同。 (如果不是,我仍然不明白发生了什么。)
如果(例如)std::vector emplace_back() 适用于任何带有显式构造函数的 T 类型,为什么它不适用于我的容器类型? 这编译得很好:
#include <iostream>
#include <vector>
template <typename T>
struct TestType
{
explicit TestType(T value)
{}
};
int main()
{
std::vector<TestType<int>> vector;
vector.emplace_back(5);
return 0;
}
感谢您的帮助!
您将 TestType<int>
指定为 std::forward
的模板参数作为 std::forward<TestType<int>>(args)...
,这意味着您将参数转发为 TestType<int>
。传递的参数试图隐式转换为 TestType<int>
,这不起作用,因为转换构造函数被标记为 explicit
.
您应该将 Args
指定为 std::forward
的模板参数,即将参数转发为:
template <typename... Args>
void emplace(TestType<int>* buffer, Args&&... args)
{
// placement new
new (buffer) TestType<int>(std::forward<Args>(args)...);
// ^^^^
}