LINUX.ORG.RU

ошибка компиляции vector<PointF>::push_back(Value)

 , ,


0

2

дано:
ubuntu 14.04
clang++3.5

class PointF
{
    void InitQPointF() const;
    void CopyMembersFrom(const Gdiplus::PointF& point);    
    PointF(const Gdiplus::PointF& point) noexcept;
    PointF& operator=(const Gdiplus::PointF& point);
public:
    QPointF getQPointF() const;

    PointF() noexcept;
    PointF(REAL x,REAL y) noexcept;    
    PointF(const Gdiplus::SizeF& size) noexcept;    
    PointF(Gdiplus::PointF&&) = default;
    BOOL Equals(const Gdiplus::PointF& point) const;
    PointF operator-(const Gdiplus::PointF& point) const;
    PointF operator+(const Gdiplus::PointF& point) const;    
    PointF& operator=(Gdiplus::PointF&&) = default;
    REAL X;
    REAL Y;
    ~PointF();
};
...
 static PointF Cvt(const POINTF& p)
    {
        returnPointF(p.x, p.y);
    }
...

std::vector<Color> gcolors;
....
 gcolors.push_back(Cvt(*i));

проблема в принципе понятна, нет специализации для
false std::__uninitialized_copy<false>

1)не понятно, почему нет реализации false?
2) по правилам с++ не помню должна ли быть для false специализация или должен использоваться общий шаблон?

на g++4.7 проблем нет, все собирается

сообщение об ошибке:

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_uninitialized.h:125:2: error: no member named '__uninit_copy' in 'std::__uninitialized_copy<false>'
        __uninit_copy(__first, __last, __result);
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_uninitialized.h:278:19: note: in instantiation of function template specialization
      'std::uninitialized_copy<std::move_iterator<PointF *>, PointF *>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_uninitialized.h:299:19: note: in instantiation of function template specialization
      'std::__uninitialized_copy_a<std::move_iterator<PointF *>, PointF *, PointF>' requested here
      return std::__uninitialized_copy_a
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/vector.tcc:421:15: note: in instantiation of function template specialization 'std::__uninitialized_move_if_noexcept_a<PointF
      *, PointF *, std::allocator<PointF> >' requested here
              = std::__uninitialized_move_if_noexcept_a
                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/vector.tcc:101:4: note: in instantiation of function template specialization 'std::vector<PointF,
      std::allocator<PointF> >::_M_emplace_back_aux<PointF>' requested here
          _M_emplace_back_aux(std::forward<_Args>(__args)...);
          ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_vector.h:932:9: note: in instantiation of function template specialization 'std::vector<PointF,
      std::allocator<PointF> >::emplace_back<PointF>' requested here
      { emplace_back(std::move(__x)); }
        ^
note: in instantiation of member function 'std::vector<PointF, std::allocator<PointF> >::push_back' requested here
            gpoints.push_back(Cvt(*i));

код из stl 4.9
#if __cplusplus < 201103L
      const bool __assignable = true;
#else
      // trivial types can have deleted assignment
      typedef typename iterator_traits<_InputIterator>::reference _RefType;
      const bool __assignable = is_assignable<_ValueType1, _RefType>::value;
#endif

      return std::__uninitialized_copy<__is_trivial(_ValueType1)
				       && __is_trivial(_ValueType2)
				       && __assignable>::
	__uninit_copy(__first, __last, __result);

добавил ассерты в код, падают ....
static_assert(__is_trivial(Gdiplus::Color));
static_assert(__is_trivial(Gdiplus::Color*));



Последнее исправление: art_corp (всего исправлений: 1)

ТС, а ты не норкоман?

std::vector<Color> gcolors;
....
 gcolors.push_back(Cvt(*i));

Класть point в вектор из Color и удивляться. Also, код - перегруженное говно, KISS.

anonymous
()
Ответ на: комментарий от anonymous

опечатка, естественно в вектор ложится:

std::vector<PointF> gpoints;
....
 points.push_back(Cvt(*i));
просто аналогичная ситуация и для Color,
он больше по размеру кода, его выкладывать не стал, это видно и из сообщения ошибки компиляции
никаких извращений с наследованием нет. Color и Point разные классы.
note: in instantiation of member function 'std::vector<PointF, std::allocator<PointF> >::push_back' requested here
            gpoints.push_back(Cvt(*i));

art_corp
() автор топика
Последнее исправление: art_corp (всего исправлений: 1)

Код тебе как-бы намекает, что в векторе возможны реаллокации, а поэтому объекты должны быть либо copy-constructable, либо move-constructable (C++11 or later). А у тебя конструктор копирования, мне кажется, приватный.

anonymous
()
Ответ на: комментарий от anonymous

Как бы намеки хорошие, но и с public конструктором ошибка повторяется.
Исходный код был:

class PointF
{
    void InitQPointF() const;
    void CopyMembersFrom(const Gdiplus::PointF& point);    
public:
    PointF(const Gdiplus::PointF& point) noexcept;
    PointF& operator=(const Gdiplus::PointF& point);
в соотв. с рекомендациями: Ensuring move is used, rather than copy

If you want to be sure that moves are being done, you can disable
copy semantics in your classes (and create wrappers for STL
classes with copying disabled), so that you when you are
moving objects of the class around, you know for sure they're
either being cheaply moved, or that the compiler will
complain if any bit of code is wanting to copy

я запретил копирование, добавил move конструктор.
Но это не верный путь.
К тому же в STL же есть шаблон для общей ситуации:
 template<bool _TrivialValueTypes>
    struct __uninitialized_copy
    {
      template<typename _InputIterator, typename _ForwardIterator>
        static _ForwardIterator
        __uninit_copy(_InputIterator __first, _InputIterator __last,
		      _ForwardIterator __result)
        {
	  _ForwardIterator __cur = __result;
	  __try
	    {
	      for (; __first != __last; ++__first, ++__cur)
		std::_Construct(std::__addressof(*__cur), *__first);
	      return __cur;
	    }
	  __catch(...)
	    {
	      std::_Destroy(__result, __cur);
	      __throw_exception_again;
	    }
	}
    };

  template<>
    struct __uninitialized_copy<true>
    {
      template<typename _InputIterator, typename _ForwardIterator>
        static _ForwardIterator
        __uninit_copy(_InputIterator __first, _InputIterator __last,
		      _ForwardIterator __result)
        { return std::copy(__first, __last, __result); }
    };

art_corp
() автор топика
Последнее исправление: art_corp (всего исправлений: 1)
Ответ на: комментарий от anonymous

К тому же класс без виртуальных функций, без ссылок и констант.
без генерации исключений

art_corp
() автор топика
Ответ на: комментарий от art_corp

А ошибка та же? Даже с учётом замечания первого анонимуса? Если так, то я больше без минимального компилируемого примера помочь не могу.

anonymous
()

Судя по сообщению об ошибке clang пытается использовать libstdc++ от gcc4.9

А gcc4.7 использует libstdc++ 4.7

Работает ли на g++4.9?

GPFault ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.