#include <vector>
#include <utility>
class A
{
public:
A(const int i):m(i){}
private:
int m;
};
int main()
{
typedef std::pair< A, std::vector< int > > pair_t;
typedef std::vector< pair_t > vector_t;
vector_t vector;
pair_t el(A(5), std::vector< int >(5, 5));
vector.push_back(el);
return 0;
}
MS VisualStudio 2008 выдаёт следующее сообщение:
error C2512: 'A::A' : no appropriate default constructor available
MS VisualStudio 2005 компилирует без проблем. Как и Comeau on-line, codepad.org
Интересное наблюдение: если изменить pair_t с
typedef std::pair< A, std::vector< int > > pair_t;
на
typedef std::pair< A, A > pair_t;
то такая конструкция уже не требует default constructor A()
С "наскоку" видна разница в реализации vector::_Insert_n()
ошибка же сама "возникает" в <memory>
template<class _InIt, class _FwdIt, class _Alloc>
inline _FwdIt _Uninit_move(
{ // use swap to instead of the copy constructor
...
// empty value used in the constructiontypename _Alloc::value_type _Val;
...
}
но с какого перепуга мы сюда вообще попадаем, мне пока неочевидно
Буду благодарен за идеи и рецепты!
Re: compiler error: no appropriate default constructor avail
Здравствуйте, Bender Bending Rodriguez, Вы писали:
BBR>но с какого перепуга мы сюда вообще попадаем, мне пока неочевидно
Это реализация move-стратегии при расширении буфера вектора.
Вектор пытается не скопировать, а перетащить данные из старого буфера в новый.
Для этого буфер предварительно заполняется пустыми объектами, после чего выполняется swap данных.
У меня нет 2008-й, и ты не привел полный список параметров, но по коду 2005-й,
template<class _InIt, class _FwdIt, class _Alloc>
inline _FwdIt _Uninit_move(
соответствует версии _Uninit_move для типов с поддержкой _Swap_move_tag.
Категория move определяется выше по стеку вызовов, и задается явным перечислением типов.
По-видимому, в 2008-й std::pair объявлен всегда поддерживающим swap ...
Имею скафандр — готов путешествовать!
Re: compiler error: no appropriate default constructor avail
Здравствуйте, rus blood, Вы писали:
RB>У меня нет 2008-й, и ты не привел полный список параметров, но по коду 2005-й, RB>
RB>template<class _InIt, class _FwdIt, class _Alloc>
RB>inline _FwdIt _Uninit_move(
RB>
RB>соответствует версии _Uninit_move для типов с поддержкой _Swap_move_tag. RB>Категория move определяется выше по стеку вызовов, и задается явным перечислением типов.
да, действительно, так и есть есть
template<class _InIt, class _FwdIt, class _Alloc>
inline
_FwdIt _Uninit_move(_InIt _First, _InIt _Last, _FwdIt _Dest,
_Alloc& _Al, _Swap_move_tag, _Range_checked_iterator_tag)
её реализация требует наличия конструктора по умолчанию для элементов последовательности.
а у _Swap_move_tag ноги растут отсюда:
<xutulity>
template<class _Ty>
struct _Is_swap_move
{ // assumes _Ty is not _Swap_move_tagstatic const bool _Value = false;
};
template<>
struct _Is_swap_move<_Swap_move_tag>
{ // reports true for _Swap_move_tagstatic const bool _Value = true;
};
template<class _Ty1,
class _Ty2>
class _Move_operation_category<pair<_Ty1, _Ty2> >
{ // reports true if either member of pair is _Swap_move_tagpublic:
typedef typename _If<
_Is_swap_move<typename _Move_operation_category<
_Ty1>::_Move_cat>::_Value || /// false для класс A
_Is_swap_move<typename _Move_operation_category<
_Ty2>::_Move_cat>::_Value, /// true для vector< int > (смотри на _Move_operation_category для вектора)
_Swap_move_tag,
_Undefined_move_tag>::_Result _Move_cat; /// получаем _Swap_move_tag, что выглядит несколько странно.
};
<vector>
// vector implements a performant swaptemplate <class _Ty, class _Ax>
class _Move_operation_category<vector<_Ty, _Ax> >
{
public:
typedef _Swap_move_tag _Move_cat;
};
Вот такие пироги.
Похоже, что пирожок был испечён SP1 для VS2008
Re[2]: compiler error: no appropriate default constructor av
Здравствуйте, uzhas, Вы писали:
U>не нашел в драфте нового стандарта требование DefaultConstructable для типа объектов в std::vector-е. U>похоже на глюк студии.
да, такого требования и нет.
это ошибка введённая Visual C++ 2008 Feature Pack(часть SP1)
Re[3]: compiler error: no appropriate default constructor av
Здравствуйте, Bender Bending Rodriguez, Вы писали:
BBR>
BBR>template<class _Ty1,
BBR> class _Ty2>
BBR> class _Move_operation_category<pair<_Ty1, _Ty2> >
BBR> { // reports true if either member of pair is _Swap_move_tag
BBR>public:
BBR> typedef typename _If<
BBR> _Is_swap_move<typename _Move_operation_category<
_Ty1>>::_Move_cat>::_Value || /// false для класс A
BBR> _Is_swap_move<typename _Move_operation_category<
_Ty2>>::_Move_cat>::_Value, /// true для vector< int > (смотри на _Move_operation_category для вектора)
BBR> _Swap_move_tag,
BBR> _Undefined_move_tag>::_Result _Move_cat; /// получаем _Swap_move_tag, что выглядит несколько странно.
BBR> };
BBR>
BBR>Вот такие пироги. BBR>Похоже, что пирожок был испечён SP1 для VS2008
А ты хочешь, чтобы твой pair_t::second копировался по значению???
А если там будет вектор на миллион интов?
Да в твоем внешнем векторе будет миллион пар...
Ну, переопредели тогда _Move_operation_category для своего pair_t и будет тебе "счастье"...
Может, проще все таки сделать ctor по-умолчанию?
Имею скафандр — готов путешествовать!
Re[4]: compiler error: no appropriate default constructor av
Здравствуйте, rus blood, Вы писали:
RB>А ты хочешь, чтобы твой pair_t::second копировался по значению??? RB>А если там будет вектор на миллион интов? RB>Да в твоем внешнем векторе будет миллион пар...
Дело не в миллионах.
Дело в том, что сам vector да и vector::push_back не предъявляют к элементам
такого требования как наличиее конструктора по умолчанию.
сурово требуется только:
23.1.3
The type of objects stored in these components must meet the requirements of CopyConstructible
types (20.1.3), and the additional requirements of Assignable types.
а тут такая незадача образовалась
именно это и послужило причиной для написания поста.
а то, что новая реализация stl от Dinkumware пытается что-то оптимизировать — так я только за.
только надо как-то разумно обрабатывать и вот такой случай.
не всегда же возможно наличие конструктора по умолчанию.
RB>Ну, переопредели тогда _Move_operation_category для своего pair_t и будет тебе "счастье"... RB>Может, проще все таки сделать ctor по-умолчанию?
Да, конструктор по умолчанию — это самое быстрое и простое решение в моём случае.