是否可以创建仅为某些模板参数添加“显式”的模板构造函数?

时间:2017-11-16 17:08:19

标签: c++

假设我有 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(或PtrINIT==OBJECT的派生类型),则必须在任何麻烦
  • 如果我将INIT设置为另一个OBJECTPtrPtr的派生,那么我必须明确说明转换。

所以,我想镜像通常的指针行为:

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> &&) { } }; ,那么构造函数不是显式的,否则它就是。

0 个答案:

没有答案