假设我有 Hide;
try
JclShell.ShellExecAndWait('C:\Windows\system32\notepad.exe');
Self.Caption := 'Notepad closed';
finally
Show;
end;
类型(指针周围的包装器),它有一个移动构造函数:
var
ATmpOnClick: TNotifyEvent;
begin
ATmpOnClick := Button1.OnClick;
Button1.OnClick := nil;
try
JclShell.ShellExecAndWait('C:\Windows\system32\notepad.exe');
Self.Caption := 'Notepad closed';
finally
Button1.OnClick := ATmpOnClick;
end;
end;
现在,我想要同时拥有这两个:
Ptr
设置为另一个template <typename OBJECT>
struct Ptr {
Ptr() { }
template <typename INIT>
/*explicit*/ Ptr(Ptr<INIT> &&) { }
};
,Ptr
(或Ptr
是INIT==OBJECT
的派生类型),则必须在任何麻烦INIT
设置为另一个OBJECT
,Ptr
是Ptr
的派生,那么我必须明确说明转换。所以,我想镜像通常的指针行为:
OBJECT
因此,在INIT
:
struct Base { };
struct Der: Base { };
int main() {
Base *b;
Der *d;
b = d; // compiles fine
d = static_cast<Der *>(b); // cast needed
}
有可能这样做吗?我已经尝试过SFINAE,但这不能编译(因为第二个移动构造函数是重新声明):
Ptr
如果Ptr<Base> fn(); // fn returns Ptr<Base>, for which the contained object is actually a Der
int main() {
Ptr<Base> b = Ptr<Der>(); // compiles fine
Ptr<Der> d = fn(); // should NOT compile
Ptr<Der> d = Ptr<Der>(fn()); // I need to be explicitly convert Ptr<Base> to Ptr<Der> to compile
}
可以转换为template <typename OBJECT>
struct Ptr {
Ptr() { }
template <typename INIT, typename = std::enable_if_t<std::is_convertible_v<INIT *, OBJECT *>>>
Ptr(Ptr<INIT> &&) { }
template <typename INIT, typename = std::enable_if_t<!std::is_convertible_v<INIT *, OBJECT *>>>
explicit Ptr(Ptr<INIT> &&) { }
};
,那么构造函数不是显式的,否则它就是。