gpt4 book ai didi

c++ - 如果找到函数,则启用复制构造函数

转载 作者:太空狗 更新时间:2023-10-29 21:09:47 25 4
gpt4 key购买 nike

我有一个围绕 Foo* 的 RAII 包装器,其中 Foo 是一个库。

类看起来很像这样:

struct Handle{
Foo* p;
Handle(): p(foo_new()){}
Handle(Handle&& f): p(std::exchange(f.p, nullptr)){}
Handle(const Handle& f){
p = foo_clone(f.p);
}
};

为简洁起见,省略了错误处理和赋值运算符。

现在的问题是,foo_clone 在 1 个库版本中可用,但在较早的版本中不可用,包装器应该同时支持这两种版本。没有要检查的 *_VERSION 宏,所以我需要用 C++ 而不是预处理器来检查。

我想到了这样的事情:

template<class T, decltype(foo_clone(std::declval<T>().p)) = nullptr>
Handle(const T& f){...}

但这不起作用:定义的 move-ctor 要求我逐字添加一个复制 ctor 作为 Handle(const Handle&),似乎不允许模板欺骗,否则编译器会考虑复制- ctor 被隐式​​删除。

我能做什么?

最佳答案

你确实不能 SFINAE 那个不应该是模板的特殊成员。

所以你可以模板类本身:

// I let you implement traits has_foo_clone<T>


template <typename T, bool = has_foo_clone<T>::value>
struct HandleImpl
{
T* p;
HandleImpl(): p(foo_new()) {}
HandleImpl(HandleImpl&& f): p(std::exchange(f.p, nullptr)){}
HandleImpl(const HandleImpl& f){ p = foo_clone(f.p); }
};

template <typename T>
struct HandleImpl<T, false>
{
T* p;
HandleImpl(): p(foo_new()) {}
HandleImpl(HandleImpl&& f): p(std::exchange(f.p, nullptr)){}
HandleImpl(const HandleImpl& f) = delete;
};

using Handle = HandleImpl<Foo>;

在 C++20 中,由于要求“丢弃”方法,您可能会做得更好:

template <typename T>
struct HandleImpl
{
T* p;
HandleImpl(): p(foo_new()) {}
HandleImpl(HandleImpl&& f): p(std::exchange(f.p, nullptr)){}
HandleImpl(const HandleImpl& f) requires(has_foo_clone<T>::value) { p = foo_clone(f.p); }
};

using Handle = HandleImpl<Foo>;

关于c++ - 如果找到函数,则启用复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57258588/

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