Clang: оператор присваивания копии удаляется при использовании std :: Map в libc ++ - PullRequest
0 голосов
/ 04 октября 2018

При сборке PROJ_XXX я столкнулся с некоторыми ошибками сборки.Я делаю изменения для перехода с gnustl lib на libc ++.

Ошибки сборки

f:\office\build\droidx86\debug\proj_xxxx\test\android\objd\droidx86\clang-temp\EventPerfTrackerTests.cpp
Exit code: 0
Running: f:\androidndk.16.1.1\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe @f:\office\build\droidx86\debug\proj_xxxx\test\android\objd\droidx86\android_clang_cpp_flags.rsp -c f:\office\dev\proj_xxxx\test\android\..\EventPerfTrackerTests.cpp -o f:\office\build\droidx86\debug\proj_xxxx\test\android\objd\droidx86\clang-temp\EventPerfTrackerTests.cpp\compile.tmp
In file included from f:\office\dev\proj_xxxx\test\android\..\EventPerfTrackerTests.cpp:1:
In file included from F:/Office/dev/liblet/precomp/android\precomp.h:1:
In file included from F:/Office/Import/droidx86/debug/proj_xxxx/x-none/droidx86/inc\sharedPch/sharedPch_android.h:9:
In file included from F:/Office\Import\droidx86\debug\proj_xxxx\x-none\droidx86\inc\sharedPch\sharedPch.h:39:
In file included from F:/Office\Import\droidx86\debug\proj_xxxx\x-none\droidx86\inc\msoSTL.h:53:
f:/nugetcache\androidndk.16.1.1\sources\cxx-stl\llvm-libc++\include\map(629,15) :  error: object of type 'std::__ndk1::pair<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>' cannot be assigned because its copy assignment operator is implicitly deleted
        {__nc = __v.__cc; return *this;}
              ^
f:/nugetcache\androidndk.16.1.1\sources\cxx-stl\llvm-libc++\include\__tree(1645,35) :  note: in instantiation of member function 'std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>::operator=' requested here
                __cache->__value_ = *__first;
                                  ^
f:/nugetcache\androidndk.16.1.1\sources\cxx-stl\llvm-libc++\include\__tree(1575,9) :  note: in instantiation of function template specialization 'std::__ndk1::__tree<std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>, std::__ndk1::__map_value_compare<const wchar_t *const, std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>, std::__ndk1::less<const wchar_t *const>, true>, std::__ndk1::allocator<std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData> > >::__assign_multi<std::__ndk1::__tree_const_iterator<std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>, std::__ndk1::__tree_node<std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>, void *> *, int> >' requested here
        __assign_multi(__t.begin(), __t.end());
        ^
f:/nugetcache\androidndk.16.1.1\sources\cxx-stl\llvm-libc++\include\map(912,21) :  note: in instantiation of member function 'std::__ndk1::__tree<std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>, std::__ndk1::__map_value_compare<const wchar_t *const, std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>, std::__ndk1::less<const wchar_t *const>, true>, std::__ndk1::allocator<std::__ndk1::__value_type<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData> > >::operator=' requested here
            __tree_ = __m.__tree_;
                    ^
f:\office\dev\proj_xxxx\test\android\..\EventPerfTrackerTests.cpp(50,27) :  note: in instantiation of member function 'std::__ndk1::map<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData, std::__ndk1::less<const wchar_t *const>, std::__ndk1::allocator<std::__ndk1::pair<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData> > >::operator=' requested here
                m_latestSTEDataReceived = dataMap;
                                        ^
f:/nugetcache\androidndk.16.1.1\sources\cxx-stl\llvm-libc++\include\Utility(325,5) :  note: copy assignment operator is implicitly deleted because 'pair<const wchar_t *const, ::proj_xxxx::EventPerfTrackerSTEData>' has a user-declared move constructor
    pair(pair&&) = default;
    ^
1 error generated.
Exit code: 1

Исходя из этой ошибки, мне кажется, что существует конфликт ч / б с оператором перемещения и копирования, и из-за чего назначение копирования помечается как удаленное.Это происходит для класса Pair, определенного в классе limit.cpp.Я также рассмотрел определение класса Pair в libc ++ и увидел, что оператор присваивания copy & move явно определен, поэтому мне интересно, почему это происходит.Я также проверил определение класса Pair в gnustl, и я не смог увидеть каких-либо существенных отличий, которые я мог заподозрить.

Определение оператора присваивания и копирования: -

_LIBCPP_INLINE_VISIBILITY
    pair& operator=(typename conditional<
                        is_copy_assignable<first_type>::value &&
                        is_copy_assignable<second_type>::value,
                    pair, __nat>::type const& __p)
        _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
                   is_nothrow_copy_assignable<second_type>::value)
    {
        first = __p.first;
        second = __p.second;
        return *this;
    }

    _LIBCPP_INLINE_VISIBILITY
    pair& operator=(typename conditional<
                        is_move_assignable<first_type>::value &&
                        is_move_assignable<second_type>::value,
                    pair, __nat>::type&& __p)
        _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
                   is_nothrow_move_assignable<second_type>::value)
    {
        first = _VSTD::forward<first_type>(__p.first);
        second = _VSTD::forward<second_type>(__p.second);
        return *this;
    }

Код ошибки:

const size_t NumDurationBuckets = 7;

struct EventPerfTrackerSTEData
{
       std::uint32_t m_timeSettingInSeconds;
       std::uint32_t m_timeActualInSeconds;
       std::uint32_t m_totalEventsInTimew;
       std::uint32_t m_maxEventDurationSeenInTime;
       std::array<uint32_t, NumDurationBuckets> m_durationBucketsEventCounts;
};
       virtual void SendData(const std::map<const wchar_t * const, EventPerfTrackerSTEData> &dataMap) noexcept override
       {
              ++m_timesSendEventCalled;
              m_latestSTEDataReceived = dataMap;
       }

       std::map<const wchar_t * const, EventPerfTrackerSTEData> m_latestSTEDataReceived;

Я также могу скопировать сценарий сбоя сборки с моим тестовым кодом в моей среде разработки. Но тот же сценарий проходит и на компиляторе GCC, и на IdeOne.

Любая помощь приветствуется.

Версия NDK: - 16r Мин. Версия SDK: 21

С уважением,

Бхупеш

1 Ответ

0 голосов
/ 28 октября 2018

Компилятор Clang имеет ограничение с libc ++ для класса карты.Конструкторы копирования, вероятно, удалены, потому что тип ключа является const.Если ключ имеет тип const, он не может быть назначен во время конструктора копирования.Однако не уверен, почему сообщение об ошибке ссылается на конструктор перемещения.

Технически: -

_LIBCPP_INLINE_VISIBILITY
    pair& operator=(typename conditional<
                        is_copy_assignable<first_type>::value &&
                        is_copy_assignable<second_type>::value,
                    pair, __nat>::type const& __p)
        _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
                   is_nothrow_copy_assignable<second_type>::value)
    {
        first = __p.first;
        second = __p.second;
        return *this;
    }

is_copy_assignable возвращает false, поэтому оператор копирования пары = не создан.Это специфическое поведение Clang.

...