【发布时间】:2019-08-01 18:57:40
【问题描述】:
我有一个围绕 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&),似乎不允许使用模板欺骗,否则编译器会认为 copy-ctor 被隐式删除。
我能做什么?
【问题讨论】:
-
@Paulo1205:OP 的主要问题是针对无法模板化的 SFINAE 特殊成员。即使 OP 的检测代码不正确。
-
您确定代码不正确?
foo_clone(如果存在)返回一个指针,因此此方法类似于template<T, std::enable_if_t<...>* = nullptr>对于布尔解决方案,当然必须使用另一种方法。 -
@Flamefire:至少有:
std::declval<T>::p->std::declval<T>().p。可能被视为错字或您的问题。 -
谢谢,已修复。在修改 SO 的代码时确实是一个错字
标签: c++ constructor sfinae