Re[6]: std::map + insert() + std::move()
От: Evgeny.Panasyuk Россия  
Дата: 11.04.14 08:41
Оценка: 18 (1) +2
Здравствуйте, niXman, Вы писали:

EP>>Генерируется, но не в данном случае.

X>почему не в данном случае? а в каких случаях генерируется?

Выше была ссылка на Страуструпа.
А вот ISO:

12.8 Copying and moving class objects
9 If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared
as defaulted if and only if
— X does not have a user-declared copy constructor,
— X does not have a user-declared copy assignment operator,
— X does not have a user-declared move assignment operator, and
— X does not have a user-declared destructor.


В твоём случае, можешь просто добавить:
noncopyable(noncopyable &&) = default;
Re: std::map + insert() + std::move()
От: DarkEld3r  
Дата: 10.04.14 12:31
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>ЧЯДНТ?

Не добавляешь move-конструктор?
noncopyable(noncopyable &&) { cout << "move constructor" << endl; }
Re[4]: std::map + insert() + std::move()
От: Evgeny.Panasyuk Россия  
Дата: 10.04.14 15:08
Оценка: +1
Здравствуйте, uzhas, Вы писали:

U>сущность должна быть перемещаемой, для этого надо написать соответствущий конструктор (такой конструктор не генерируется по умолчанию)


Генерируется, но не в данном случае.
std::map + insert() + std::move()
От: niXman Ниоткуда https://github.com/niXman
Дата: 10.04.14 12:11
Оценка:
приветствую!

я таки недоучил move-semantics и от того что-то не въезжаю %)

есть такой пример:
#include <iostream>
#include <map>

struct noncopyable {
    noncopyable() {std::cout << "noncopyable ctor" << std::endl;}
    noncopyable(const noncopyable &) = delete;
    noncopyable& operator=(const noncopyable &) = delete;
};

int main() {
    std::map<int, noncopyable> cp;
    cp.insert(std::make_pair(3, noncopyable()));
}

не компилится. говорит:

g++ -std=c++11 mapmove.cpp -omapmove && ./mapmove
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from mapmove.cpp:2:
/usr/include/c++/4.8/bits/stl_pair.h: In instantiation of ‘constexpr std::pair<_T1, _T2>::pair(_U1&&, const _T2&) [with _U1 = int; <template-parameter-2-2> = void; _T1 = int; _T2 = noncopyable]’:
/usr/include/c++/4.8/bits/stl_pair.h:281:72: required from ‘constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = noncopyable; typename std::__decay_and_strip<_T2>::__type = noncopyable; typename std::__decay_and_strip<_Tp>::__type = int]’
mapmove.cpp:18:43: required from here
/usr/include/c++/4.8/bits/stl_pair.h:134:45: error: use of deleted function ‘noncopyable::noncopyable(const noncopyable&)’
: first(std::forward<_U1>(__x)), second(__y) { }
^
mapmove.cpp:12:2: error: declared here
noncopyable(const noncopyable &) = delete;
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from mapmove.cpp:2:
/usr/include/c++/4.8/bits/stl_pair.h: In instantiation of ‘constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = noncopyable; typename std::__decay_and_strip<_T2>::__type = noncopyable; typename std::__decay_and_strip<_Tp>::__type = int]’:
mapmove.cpp:18:43: required from here
/usr/include/c++/4.8/bits/stl_pair.h:281:72: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = int; _T2 = noncopyable]’
return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
^
/usr/include/c++/4.8/bits/stl_pair.h:128:17: note: ‘constexpr std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = int; _T2 = noncopyable]’ is implicitly deleted because the default definition would be ill-formed:
constexpr pair(pair&&) = default;
^
/usr/include/c++/4.8/bits/stl_pair.h:128:17: error: use of deleted function ‘noncopyable::noncopyable(const noncopyable&)’
mapmove.cpp:12:2: error: declared here
noncopyable(const noncopyable &) = delete;
^
mapmove.cpp: In function ‘int main()’:
mapmove.cpp:18:44: error: no matching function for call to ‘std::map<int, noncopyable>::insert(std::pair<int, noncopyable>)’
cp.insert(std::make_pair(3, noncopyable()));
^
mapmove.cpp:18:44: note: candidates are:
In file included from /usr/include/c++/4.8/map:61:0,
from mapmove.cpp:3:
/usr/include/c++/4.8/bits/stl_map.h:594:7: note: std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const value_type&) [with _Key = int; _Tp = noncopyable; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, noncopyable> >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const int, noncopyable> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const int, noncopyable>]
insert(const value_type& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:594:7: note: no known conversion for argument 1 from ‘std::pair<int, noncopyable>’ to ‘const value_type& {aka const std::pair<const int, noncopyable>&}’
/usr/include/c++/4.8/bits/stl_map.h:602:9: note: template<class _Pair, class> std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(_Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = int; _Tp = noncopyable; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, noncopyable> >]
insert(_Pair&& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:602:9: note: template argument deduction/substitution failed:
/usr/include/c++/4.8/bits/stl_map.h:598:32: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
template<typename _Pair, typename = typename
^
/usr/include/c++/4.8/bits/stl_map.h:615:7: note: void std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::initializer_list<std::pair<const _Key, _Tp> >) [with _Key = int; _Tp = noncopyable; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, noncopyable> >]
insert(std::initializer_list<value_type> __list)
^
/usr/include/c++/4.8/bits/stl_map.h:615:7: note: no known conversion for argument 1 from ‘std::pair<int, noncopyable>’ to ‘std::initializer_list<std::pair<const int, noncopyable> >’
/usr/include/c++/4.8/bits/stl_map.h:644:7: note: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, const value_type&) [with _Key = int; _Tp = noncopyable; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, noncopyable> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, noncopyable> >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, noncopyable> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const int, noncopyable>]
insert(const_iterator __position, const value_type& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:644:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/4.8/bits/stl_map.h:655:9: note: template<class _Pair, class> std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, _Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = int; _Tp = noncopyable; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, noncopyable> >]
insert(const_iterator __position, _Pair&& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:655:9: note: template argument deduction/substitution failed:
mapmove.cpp:18:44: note: cannot convert ‘std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = noncopyable; typename std::__decay_and_strip<_T2>::__type = noncopyable; typename std::__decay_and_strip<_Tp>::__type = int]((* & noncopyable()))’ (type ‘std::pair<int, noncopyable>’) to type ‘std::map<int, noncopyable>::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const int, noncopyable> >}’
cp.insert(std::make_pair(3, noncopyable()));
^
In file included from /usr/include/c++/4.8/map:61:0,
from mapmove.cpp:3:
/usr/include/c++/4.8/bits/stl_map.h:670:9: note: template<class _InputIterator> void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = int; _Tp = noncopyable; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, noncopyable> >]
insert(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.8/bits/stl_map.h:670:9: note: template argument deduction/substitution failed:
mapmove.cpp:18:44: note: candidate expects 2 arguments, 1 provided
cp.insert(std::make_pair(3, noncopyable()));
^

(а как тут сделать спойлер?)

пробовал вписывать std::move() и так:
    cp.insert(std::make_pair(3, std::move(noncopyable())));

и так:
    cp.insert(std::move(std::make_pair(3, noncopyable())));


ЧЯДНТ?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: std::map + insert() + std::move()
От: niXman Ниоткуда https://github.com/niXman
Дата: 10.04.14 12:39
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

DE>Не добавляешь move-конструктор?

я тоже такое предположил, но не уверен что это требование обязано выполняться...

подожду, может еще кто-то подтвердит...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: std::map + insert() + std::move()
От: placement_new  
Дата: 10.04.14 12:56
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, DarkEld3r, Вы писали:


DE>>Не добавляешь move-конструктор?

X>я тоже такое предположил, но не уверен что это требование обязано выполняться...

X>подожду, может еще кто-то подтвердит...


Обязано

http://www.stroustrup.com/C++11FAQ.html#default2
Re[3]: std::map + insert() + std::move()
От: uzhas Ниоткуда  
Дата: 10.04.14 15:03
Оценка:
Здравствуйте, niXman, Вы писали:

X>я тоже такое предположил, но не уверен что это требование обязано выполняться...


сущность должна быть перемещаемой, для этого надо написать соответствущий конструктор (такой конструктор не генерируется по умолчанию)
Re[5]: std::map + insert() + std::move()
От: uzhas Ниоткуда  
Дата: 10.04.14 15:17
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Генерируется, но не в данном случае.


виноват, не знал на чем остановились стандартизаторы, ведь там споры были на эту тему
Re[6]: std::map + insert() + std::move()
От: Evgeny.Panasyuk Россия  
Дата: 10.04.14 15:24
Оценка:
Здравствуйте, uzhas, Вы писали:

U>виноват, не знал на чем остановились стандартизаторы, ведь там споры были на эту тему


Что-то тоже припоминаю на эту тему.
Re[5]: std::map + insert() + std::move()
От: niXman Ниоткуда https://github.com/niXman
Дата: 11.04.14 08:34
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Генерируется, но не в данном случае.

почему не в данном случае? а в каких случаях генерируется?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.