gpt4 book ai didi

C++ - 为什么编译器不能推断出包含构造函数参数的函数模板的类型?

转载 作者:行者123 更新时间:2023-12-03 07:55:54 24 4
gpt4 key购买 nike

我想使用std::aligned_storage_t为了解耦分配和构造,所以我写了两个小助手来帮助我做到这一点

#include <type_traits>
template <typename T>
using Uninitialized = std::aligned_storage_t<sizeof(T), alignof(T)>;

template <typename T, typename... Args>
auto get_initialized(Uninitialized<T>& block, Args... args) -> T&
requires(
// If we allow type with default constructor, then it would be ambiguous
// if the caller wants initialization or simply getting reference.
!std::is_default_constructible_v<T> &&
(sizeof...(Args) == 0 || std::is_constructible_v<T, Args...>)
)
{
T* p = (T*) &block;
if constexpr (sizeof...(Args) > 0)
new (p) T{args...};
return *p;
}

我测试了它

class Obj {
public:
Obj() = delete;
Obj(const char* s) noexcept : m_str(s) {}

void print() noexcept {
std::cout << m_str << std::endl;
}
private:
const char* m_str = nullptr;
};

int main() {
Uninitialized<Obj> obj{};
const char* s = "Test";
Obj& o = get_initialized(obj, s);
o.print();
}

但它失败了。我尝试过 clang、gcc 和 msvc,它们都提示“没有匹配的函数调用”。来自 clang 的投诉

<source>:37:14: error: no matching function for call to 'get_initialized'
Obj& o = get_initialized(obj, s);
^~~~~~~~~~~~~~~

当然,只需添加 <Obj>该代码可以正常工作。但我只是想在这里节省一些打字。我发现 gcc 的输出在这里提供了一些见解

<source>:37:29: error: no matching function for call to 'get_initialized(Uninitialized<Obj>&, const char*&)'
37 | Obj& o = get_initialized(obj, s);
| ~~~~~~~~~~~~~~~^~~~~~~~

所以我猜问题与构造函数的参数类型有关,我也很好奇为什么s的类型会这样将被推导为 char*&而它只是一个 8 字节数据,无需额外费用即可复制。那么有没有办法强制复制参数,就像 std::refstd::cref

最佳答案

Uninitialized<T>是一个别名...

所以你的模板实际上是

使用未初始化=;

template <typename T, typename... Args>
auto get_initialized(std::aligned_storage_t<sizeof(T), alignof(T)>& block, Args... args) -> T&

T此处不可推导(任何具有相同 sizeof/alignof 的类都是有效的)。

参见Deduction_from_a_type了解更多信息

关于C++ - 为什么编译器不能推断出包含构造函数参数的函数模板的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76066147/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com