Skip to content
  • Igor Kushnir's avatar
    Prevent copying and moving ScopedDialog · 2f2db958
    Igor Kushnir authored
    https://ericniebler.com/2013/08/07/universal-references-and-the-copy-constructo
    describes the issue solved by this commit. The blog post recommends
    constraining the forwarding-reference constructor. But that solution
    would require much more code than added in this commit. Especially
    because the constraint would have to be expanded to support template
    parameter pack.
    
    The deleted constructor overloads prevent surprising and undesirable
    compilation of the following two code snippets:
        ScopedDialog<QDialog> s;
        ScopedDialog<QDialog> s2(s);
    and
        const ScopedDialog<QDialog> s;
        ScopedDialog<QDialog> s2(std::move(s));
    They were compiled successfully because the forwarding-reference
    constructor was a better match than the deleted copy and move
    constructor respectively (due to const-qualifier differences). In the
    forwarding-reference constructor invoked in these snippets, a reference
    to ScopedDialog `s` was implicitly converted to QDialog* and passed as a
    parent to `s2`'s new QDialog.
    
    The final specifier prevents surprising and undesirable compilation of
    the following code snippet (as well as the 3 other const and
    rvalue-reference variations of it):
    ```
    template <typename T> class ScopedDerived : public ScopedDialog<T> {};
    void f() {
        ScopedDerived<QDialog> s;
        ScopedDialog<QDialog> s2(s);
    }
    ```
    
    A volatile ScopedDialog (which does not make sense, by the way) cannot
    be copied or moved for another reason: passing volatile ScopedDialog as
    `this` argument to `operator DialogType*() const` discards qualifiers.
    2f2db958