Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
tapochka
40 / 40 / 17
Регистрация: 25.04.2014
Сообщений: 499
1

Emplace в std::map. Как добавить элемент в std::map без копирования?

27.01.2016, 02:07. Просмотров 1959. Ответов 21
Метки нет (Все метки)

здравствуйте... есть ли способ не писать так:
C++
1
2
3
4
std::map<int, char> ksa;
ksa.emplace(std::piecewise_construct,
    std::forward_as_tuple(1),
    std::forward_as_tuple('a'));
чтобы добавить элемент без копирования в std::map?

пробовал:
C++
1
2
typedef std::map<int, char> char_map;
typedef std::invoke<&char_map::emplace, 1, 'a'>::type please;
все валится...
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.01.2016, 02:07
Ответы с готовыми решениями:

Std::map::emplace
То ли я туплю/криво поставил компилятор, то ли это emplace синтаксис кривой,...

Возможно ли создать контейнер std::map, в котором в качестве значения была бы ссылка на std::map?
Здравствуйте. Возможно ли создать контейнер std::map, в котором в качестве...

Стоит ли очищать в деструкторе std::map , std::vecotor?
У меня ещё один нубский вопрос :) Вот если в классе объявлены мапы и вектора,...

std::map, std::vector и порядок обхода коллекции
Здравствуйте, уважаемые! Вопрос следующий - если я сохраняю какие-то значения...

Std::vector добавить новый элемент собственного класса без использования конструктора копирования
Всем привет! Есть один класс, который я хочу хранить в std::vector. Создать...

21
Croessmah
++Ͻ
14776 / 8452 / 1605
Регистрация: 27.09.2012
Сообщений: 20,800
Записей в блоге: 2
Завершенные тесты: 1
27.01.2016, 02:16 2
Для начала хотелось бы разобраться,
чем не устраивает способ
C++
1
ksa.emplace(1, 'a') ;
1
tapochka
40 / 40 / 17
Регистрация: 25.04.2014
Сообщений: 499
27.01.2016, 02:19  [ТС] 3
омг... что-то я тупанул
вроде ж раньше нельзя было вашим способом добавлять
0
Croessmah
++Ͻ
14776 / 8452 / 1605
Регистрация: 27.09.2012
Сообщений: 20,800
Записей в блоге: 2
Завершенные тесты: 1
27.01.2016, 02:23 4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <map>
 
 
 
struct Test
{
    Test(int x): x_(x) { std::cout << "ctor" << std::endl ;}
    Test(const Test& src): x_(src.x_) { std::cout << "cctor" << std::endl ;}
    Test& operator=(const Test& src) { x_ = src.x_ ; std::cout << "ass" << std::endl ; return *this; }
    ~Test() { std::cout << "dtor" << std::endl ;}
    int x_ ;
} ;
 
 
std::ostream& operator<<(std::ostream& stream, const Test& obj)
{
    return stream << obj.x_ ;
}
 
 
int main()
{
    std::map<int, Test> ksa;
    ksa.emplace(1, 10) ;
    ksa.emplace(2, 5) ;
    ksa.emplace(3, 6) ;
    ksa.emplace(4, 7) ;
    for(auto& e: ksa)
        std::cout << e.first << " : " << e.second << std::endl ;
}
http://rextester.com/XGLFD32583

никакого копирования.
1
tapochka
40 / 40 / 17
Регистрация: 25.04.2014
Сообщений: 499
27.01.2016, 03:01  [ТС] 5
Croessmah, а не подскажете через std::invoke как запилить... интересно даже стало, сам не допер пока
0
Croessmah
++Ͻ
14776 / 8452 / 1605
Регистрация: 27.09.2012
Сообщений: 20,800
Записей в блоге: 2
Завершенные тесты: 1
27.01.2016, 03:23 6
Цитата Сообщение от tapochka Посмотреть сообщение
а не подскажете через std::invoke как запилить...
Как будет у меня компилятор, с поддержкой c++17,
так посмотрю, а пока даже не лезу туда
0
tapochka
40 / 40 / 17
Регистрация: 25.04.2014
Сообщений: 499
27.01.2016, 04:58  [ТС] 7
походу это принципиально нереально, учитывая, что emplace возвращает черти что

Добавлено через 8 минут
из-за этого и через bind не получится походу
C++
1
std::bind(&char_map::emplace, ksa, 1, 'a')();
0
ForEveR
В астрале
Эксперт С++
7997 / 4755 / 652
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
27.01.2016, 10:35 8
tapochka, Интересный вопрос. Но дело точно не в том что возвращает emplace. Вот так работает:
C++
1
2
3
   std::map<int, int> map;
   auto f = std::bind(&std::map<int, int>::emplace<int, int>, std::ref(map), std::placeholders::_1, std::placeholders::_2);
   f(1, 2);
Если же передать прям значения в bind - работать не будет. Тоже самое с vector::emplace_back.

Добавлено через 5 минут
С invoke все попроще:
C++
1
std::invoke(&std::map<int, int>::emplace<int, int>, std::ref(map), 1, 2);
2
Kastaneda
27.01.2016, 10:43
  #9

Не по теме:

Цитата Сообщение от ForEveR Посмотреть сообщение
std::invoke
крутая штука, мы в одном низкоуровневом проекте целую библиотеку для этого тянули, чтоб не зависеть от calling convention. std::invoke похоже решает эту проблему.

0
gromo
376 / 275 / 30
Регистрация: 04.09.2009
Сообщений: 1,223
27.01.2016, 11:21 10
Kastaneda, можно подробнее каким образом std::invoke абстрагирует от calling convention?
0
Kastaneda
Jesus loves me
Эксперт С++
4946 / 3023 / 346
Регистрация: 12.12.2009
Сообщений: 7,626
Записей в блоге: 2
Завершенные тесты: 1
27.01.2016, 11:35 11
gromo, конкретно std::invoke еще не смотрел.
Зачем мы у себя тянули левую библиотеку - у нас генерился ассемблер в рантайме, который потом исполнялся. Целевую платформу не знаем, нужно вызвать ф-цию - как вызвать? Куда аргументы класть? Кто стек почистит? Вот для этого есть готовая обертка в виде библиотеки (забыл как называется). Если std::invoke позволяет делать тоже самое без левой библиотеки, то это круто! Но повторюсь, я не смотрел еще что там внутри, просто кажется, что ее в стандарт добавили не только для того, чтобы вместо f() можно было писать invoke(f), должен быть более глубокий смысл.
1
ct0r
Игогошка!
1789 / 690 / 44
Регистрация: 19.08.2012
Сообщений: 1,343
Завершенные тесты: 1
27.01.2016, 12:50 12
Цитата Сообщение от Kastaneda Посмотреть сообщение
Но повторюсь, я не смотрел еще что там внутри, просто кажется, что ее в стандарт добавили не только для того, чтобы вместо f() можно было писать invoke(f), должен быть более глубокий смысл.
The aim of this proposal is to introduce the function template invoke that provide uniform semantics for invoking all C++ callable types which includes: function pointers, member pointers and functors.
...
template<typename F>
auto deref_fn(F&& f)
{
return [f](auto&&... args) { return *std::invoke(f, std::forward<decltype(args)>(args)...); };
}
Вот собственно и весь смысл. Без invoke пришлось бы использовать sfinae и mem_fn.
2
Kastaneda
27.01.2016, 12:51
  #13

Не по теме:

Цитата Сообщение от ct0r Посмотреть сообщение
Вот собственно и весь смысл
а, ну тогда не интересно:(

0
tapochka
40 / 40 / 17
Регистрация: 25.04.2014
Сообщений: 499
27.01.2016, 22:18  [ТС] 14
Цитата Сообщение от ForEveR Посмотреть сообщение
std::invoke(&std::map<int, int>::emplace<int, int>, std::ref(map), 1, 2);
ошибка на vs2015

Цитата Сообщение от ForEveR Посмотреть сообщение
Если же передать прям значения в bind - работать не будет
а почему так?
0
ForEveR
В астрале
Эксперт С++
7997 / 4755 / 652
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
28.01.2016, 00:12 15
tapochka, Не знаю что там с VS, на gcc/clang работает. А почему если передать значения в bind не работает - не знаю.
0
Kastaneda
Jesus loves me
Эксперт С++
4946 / 3023 / 346
Регистрация: 12.12.2009
Сообщений: 7,626
Записей в блоге: 2
Завершенные тесты: 1
28.01.2016, 06:28 16
Цитата Сообщение от ForEveR Посмотреть сообщение
А почему если передать значения в bind не работает - не знаю.
map же скопируется и emplace будет вызвана для скопированного map'а, а не для оригинального. std::bind() внутри себя хранит переданные аргументы - передашь копии, будут храниться копии, передашь ссылки, будут храниться ссылки.
0
ForEveR
В астрале
Эксперт С++
7997 / 4755 / 652
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
28.01.2016, 08:45 17
Kastaneda, Не работает не в том плане. Даже если передать с std::ref - ошибка компиляции на вызове полученной функции без аргументов.
0
Kastaneda
Jesus loves me
Эксперт С++
4946 / 3023 / 346
Регистрация: 12.12.2009
Сообщений: 7,626
Записей в блоге: 2
Завершенные тесты: 1
28.01.2016, 08:49 18
ForEveR, что-то не догоняю о чем речь. Думал об этом
C++
1
2
3
   std::map<int, int> map;
   auto f = std::bind(&std::map<int, int>::emplace<int, int>, std::ref(map), std::placeholders::_1, std::placeholders::_2);
   f(1, 2);
Добавлено через 55 секунд
а, понял, речь об аргументах?
0
ForEveR
В астрале
Эксперт С++
7997 / 4755 / 652
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
28.01.2016, 08:49 19
Kastaneda, Не совсем. Имелось ввиду, что не будет работать так:
C++
1
2
auto f = std::bind(&std::map<int, int>::emplace<int, int>, std::ref(map), 1, 2);
f();
0
Kastaneda
Jesus loves me
Эксперт С++
4946 / 3023 / 346
Регистрация: 12.12.2009
Сообщений: 7,626
Записей в блоге: 2
Завершенные тесты: 1
28.01.2016, 09:11 20
ForEveR, сижу под виндой, студия 13 даже рабочий вариант не компилит. Что-то не могу причину понять, странно. В gcc писал такое.
0
28.01.2016, 09:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2016, 09:11

std::map find. Получить ключ(элемент) и как записать все данные при объявлений?
Вопрос первый: как получить ключ контейнера map по данным? например: // id,...

Как формируется размер std::map?
ожидал увидеть размер 18. По 5 байт на две строки и по 4 байта на два int-а....

Как реализован .end() std::map?
Как реализован .end() std::map? Не понимаю, какая у него реализация. Либо он...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru