Странное изменение в диагностике clang с c ++ 17 - PullRequest
0 голосов
/ 11 марта 2020

Так что, в общем, это скорее вопрос юриста по теоретическому языку, чем актуальный. Во время борьбы с шаблоном из-за неясной ошибки шаблона я обнаружил поведение, которое не смог объяснить с помощью clang (нижняя строка - нет предупреждения, что я пытаюсь переместить класс, который не может быть перемещен). Странно то, что поведение clang меняется в зависимости от того, присутствует -std=c++17 или нет.

Итак, вот MVP проблемы:

#include <utility>

struct INoLikeToMoveIt
{
    INoLikeToMoveIt() = default;
    INoLikeToMoveIt(const INoLikeToMoveIt&) = delete;
    INoLikeToMoveIt(INoLikeToMoveIt&&) = delete;
    INoLikeToMoveIt& operator=(const INoLikeToMoveIt&) = delete;
    INoLikeToMoveIt& operator=(INoLikeToMoveIt&&) = delete;
};

int main()
{
    INoLikeToMoveIt a, b;
    auto c = std::make_pair(std::move(a), std::move(b));
    return 0;
}

Очевидно, это не будет работать (но поскольку в реальном случае неподвижный класс был членом родительского класса, скрытого глубоко в источниках, без каких-либо предупреждений о том, что он не является подвижным, я не мог сразу понять, что происходит). Поэтому, взяв этот пример на Годболт с -std=c+=17, вы получите:

n file included from <source>:1:

In file included from /opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/utility:70:

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:529:14: error: no matching constructor for initialization of '__pair_type' (aka 'pair<INoLikeToMoveIt, INoLikeToMoveIt>')

      return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));

             ^           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

<source>:15:19: note: in instantiation of function template specialization 'std::make_pair<INoLikeToMoveIt, INoLikeToMoveIt>' requested here

    auto c = std::make_pair(std::move(a), std::move(b));

                  ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:260:17: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_ConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]

      constexpr pair(const _T1& __a, const _T2& __b)

                ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:269:26: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_ConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]

      explicit constexpr pair(const _T1& __a, const _T2& __b)

                         ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:311:18: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveCopyPair()' was not satisfied [with _U1 = INoLikeToMoveIt]

       constexpr pair(_U1&& __x, const _T2& __y)

                 ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:318:27: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveCopyPair()' was not satisfied [with _U1 = INoLikeToMoveIt]

       explicit constexpr pair(_U1&& __x, const _T2& __y)

                          ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:325:18: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_CopyMovePair()' was not satisfied [with _U2 = INoLikeToMoveIt]

       constexpr pair(const _T1& __x, _U2&& __y)

                 ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:332:17: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_CopyMovePair()' was not satisfied [with _U2 = INoLikeToMoveIt]

       explicit pair(const _T1& __x, _U2&& __y)

                ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:341:12: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]

        constexpr pair(_U1&& __x, _U2&& __y)

                  ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:350:21: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]

        explicit constexpr pair(_U1&& __x, _U2&& __y)

                           ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:229:26: note: candidate constructor template not viable: requires 0 arguments, but 2 were provided

      _GLIBCXX_CONSTEXPR pair()

                         ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:242:26: note: candidate constructor template not viable: requires 0 arguments, but 2 were provided

      explicit constexpr pair()

                         ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:291:19: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided

        constexpr pair(const pair<_U1, _U2>& __p)

                  ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:300:21: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided

        explicit constexpr pair(const pair<_U1, _U2>& __p)

                           ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:360:12: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided

        constexpr pair(pair<_U1, _U2>&& __p)

                  ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:370:21: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided

        explicit constexpr pair(pair<_U1, _U2>&& __p)

                           ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:375:9: note: candidate constructor template not viable: requires 3 arguments, but 2 were provided

        pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);

        ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:436:9: note: candidate constructor template not viable: requires 4 arguments, but 2 were provided

        pair(tuple<_Args1...>&, tuple<_Args2...>&,

        ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:303:17: note: candidate constructor not viable: requires 1 argument, but 2 were provided

      constexpr pair(const pair&) = default;

                ^

1 error generated.

Compiler returned: 1

, который я бы интерпретировал как «эй, я скажу вам, почему вы не можете все то, что на самом деле не хочу, но не то, что движущийся ctor удален ". Как только я меняю -std=c++14 того же диагноза c, но с последующими строками:

<source>:15:10: error: call to implicitly-deleted copy constructor of 'std::pair<INoLikeToMoveIt, INoLikeToMoveIt>'

    auto c = std::make_pair(std::move(a), std::move(b));

         ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:303:17: note: explicitly defaulted function was implicitly deleted here

      constexpr pair(const pair&) = default;

                ^

/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:214:11: note: copy constructor of 'pair<INoLikeToMoveIt, INoLikeToMoveIt>' is implicitly deleted because field 'first' has a deleted copy constructor

      _T1 first;                 /// @c first is a copy of the first object

          ^

<source>:6:5: note: 'INoLikeToMoveIt' has been explicitly marked deleted here

    INoLikeToMoveIt(const INoLikeToMoveIt&) = delete;
    ^

2 errors generated.

Compiler returned: 1

, который все еще не упоминает удаленный ход c -тор, но, по крайней мере, указывает мне на виновника. Изначально я подумал, эй, может быть, есть новая перегрузка / семантика для std::make_pair, которая могла бы вызвать это, но просмотр std :: make_pair не показывает каких-либо соответствующих C ++ 17 изменений. Так это просто странное поведение в диагностике или есть объяснение этому? Просто кур ios.

...