#c #std #c 20
#c #std #c 20
Вопрос:
Есть ли способ сопоставить ключи / значения одного статически инициализированного контейнера с другим статически инициализирующим? Что-то вроде этого:
#include <iostream>
#include <set>
using namespace std;
const set< pair< string, int > > my_set = {
( "three" , 3 ),
( "seven" , 7 ),
( "twelve", 12 )
};
//how to statically extract pairs' first values?
const set< string > my_strings = my_set.values().map( []( const auto amp; pair ){ return pair.first; } );
int main() {
cout << "statically initialized set:" << endl;
for ( const auto amp; v : my_strings )
cout << " " << v << endl;
}
Ожидаемый результат:
statically initialized set:
three
seven
twelve
Комментарии:
1. Больше всего вам нужно быть осторожным, если статические данные находятся внутри разных единиц перевода. Текущие ответы предполагают, что данные упорядочены в том же файле, что и ваши вопросы, и вы получили бы другие ответы, если бы это предположение было удалено.
Ответ №1:
С диапазоном-v3:
const set< string > my_strings =
my_set
| ranges::views::keys
| ranges::to<std::set>();
views::keys
есть в C 20, но ranges::to
нет.
Комментарии:
1. Для полноты картины, можете ли вы указать часть стандарта, которая гарантирует, что
my_set
она будет создана раньшеmy_strings
?2. @Jeffrey eel.is/c draft/basic.start.dynamic
3. @Barry это справедливо только для материалов в том же TU, верно? В противном случае SIOF?
4. @NoSenseEtAl Да, но вопрос примерно в том же TU.
Ответ №2:
нет необходимости в специальной библиотеке или c 20
#include <iostream>
#include <set>
using namespace std;
const set< pair< string, int > > my_set = {
{ "three" , 3 },
{ "seven" , 7 },
{ "twelve", 12 }
};
//how to statically extract pairs' first values?
const set< string > my_strings = []{
set<string> data;
for(autoamp; pair: my_set){ // or with c 20 : ranges amp; use set's InputIt constructor
data.insert(pair.first);
}
return data;
}();
int main() {
cout << "statically initialized set:" << endl;
for ( const auto amp; v : my_strings )
cout << " " << v << endl;
}
Обратите внимание, что std::set
не имеет конструктора constexpr, он не будет выполнять инициализацию во время компиляции.
Комментарии:
1. Спасибо за ответ!
my_strings
Инициализируется ли в этом случае статически? Чтоset<> ... = []{}();
означает конструкция? Где я могу прочитать об этом? Заранее спасибо.2. @Slaus Я не уверен, что вы имеете в виду под
statically
, да, он будет инициализироваться правильно, и вы не сможете его изменить, но поскольку уstd::set
него нетconstexpr
конструктора, он не будет инициализирован во время компиляции (т. Е. Обаmy_set
иmy_strings
создаются во время выполнения)3. Спасибо за ответ. Да, мне было интересно, произойдет ли инициализация во время компиляции или нет. Поэтому я предполагаю, что он инициализируется прямо перед
main()
началом выполнения…4. @Slaus и
[]{}();
это мгновенно вызываемая лямбда-функция (я не заметил, что я не отправил это сообщение: P)5. @appleapple более распространенное название для этой идиомы — IIFE: выражение функции, вызываемое немедленно