gpt4 book ai didi

c++ - unique_ptr 成员的模板化通用 setter

转载 作者:太空狗 更新时间:2023-10-29 23:38:49 26 4
gpt4 key购买 nike

我正在尝试创建一个通用的 setter,支持值和指针。我在使用指针时遇到问题。说明主要思想的最少代码:

#include <memory>
#include <variant>

class A{
int s;
};

template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<decltype(*std::declval<ptr>)>(p);
}

int main(){
std::variant<std::unique_ptr<A>> dd;
set(dd, new A);
}

编译 (gcc-7.3.0) 失败

no matching function for call to ‘std::unique_ptr<A*&& (&)() noexcept, std::default_delete<A*&& (&)() noexcept> >::unique_ptr(A* const&)’

我不知道如何获取指针类型...另外,引用从何而来? (改ptr参数没有解决)

最佳答案

你只是打错了字:

template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<decltype(*std::declval<ptr>)>(p);
// ^^^
}

std::declval 是一个函数,因此您正在编写的代码试图取消引用该函数类型。这是一件有效的事情!这就是你如何得到 A*&& (&)() noexcept

你想要的是:

template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<decltype(*std::declval<ptr>())>(p);
}

你可以通过直接使用名称p来编写更简单的:

template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<decltype(*p)>(p);
}

但这实际上可能不正确,因为 decltype(*p) 通常有一个引用类型,您必须将其删除:

template <typename uniq, typename ptr>
void set(uniq &u, const ptr &p){
u = std::unique_ptr<std::remove_reference_t<decltype(*p)>>(p);
}

现在,这段代码真的只适用于原始指针(你必须移动一个unique_ptr并且你不能转换一个 shared_ptr 到一个 unique_ptr),这样你就可以在函数签名中更清楚地表达它,这也使得主体更容易编写:

template <typename uniq, typename T>
void set(uniq &u, T* p){
u = std::unique_ptr<T>(p);
}

这最终引出了您为什么要写的问题:

set(dd, new A);

代替:

dd = std::make_unique<A>();

无论如何? 2nd 更胜一筹。

关于c++ - unique_ptr<T> 成员的模板化通用 setter ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52569000/

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