Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
hoggy
6763 / 2948 / 507
Регистрация: 15.11.2014
Сообщений: 6,624
Завершенные тесты: 1
#1

как проинициализировать std::stack<const int> obj ( std::stack<int>{} ); - C++

31.03.2017, 14:40. Просмотров 244. Ответов 10
Метки нет (Все метки)

добрый день.

вопрос в коде:

http://rextester.com/VCVVML6656

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 <stack>
 
//-std=c++14 -fopenmp -O2 -g3 -pedantic -Wall -Weffc++ -Wextra 
//-Woverloaded-virtual -Wctor-dtor-privacy -Wnon-virtual-dtor 
//-Wold-style-cast -Wconversion -Wsign-conversion -Winit-self 
//-Wunreachable-code
 
template<class T> struct item
{
    item(const T& v):val(v){}
    T val;
};
 
int main() 
{
    using  item_t = item<int>;
    using citem_t = item<const int>;
    
    using  stack_t = std::stack< item_t>;
    using cstack_t = std::stack<citem_t>;
    
    
    stack_t st;
    for(int n=0; n<10; ++n)
        st.push(n);
    
    // как проинициализировать "константную" 
    // версию стека от неконстантного?
    cstack_t cst(st); 
}
ну то есть понятно, что stack_t и cstack_t - два принципиально разных типа,
которые друг о друге ничего не знают.

ну как быть теперь в такой ситуации?

то есть, конечно можно std::stack - за борт,
и поюзать std::deque напрямки.
но интересно решение именно для std::stack

Добавлено через 35 минут
придумал вот такой костыль (вроде даже работает)
http://rextester.com/YNR17465

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
32
33
34
35
36
37
38
39
#include <iostream>
#include <stack>
 
//-std=c++14 -fopenmp -O2 -g3 -pedantic -Wall -Weffc++ -Wextra 
//-Woverloaded-virtual -Wctor-dtor-privacy -Wnon-virtual-dtor 
//-Wold-style-cast -Wconversion -Wsign-conversion -Winit-self 
//-Wunreachable-code
 
template<class T> struct item
{
    operator const T&()const { return val; }
    
    item(const T& v):val(v){}
    T val;
};
 
int main() 
{
    using  item_t = item<int>;
    using citem_t = item<const int>;
    
    using  stack_t = std::stack< item_t>;
    using cstack_t = std::stack<citem_t>;
    
    stack_t st;
    for(int n=0; n<10; ++n)
        st.push(n);
    
    // расчет на то, что строение объекта у "константной" 
    // и "не константной" версии одинаковое
    cstack_t cst;   
    new(&cst) stack_t(st);
    
    while(!cst.empty())
    {
        std::cout << cst.top()<<std::endl;
        cst.pop();
    }
}
вот интересно...
насколько это потенциально опасное решение?
вы бы пропустили такое через ревью?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.03.2017, 14:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос как проинициализировать std::stack<const int> obj ( std::stack<int>{} ); (C++):

std::string, std::fstream, ошибка кучи - C++
где то начало вылетать при операции += с локальной переменной std::string. Заменил на свой qString. Замечательно, то же самое... ошибка при...

Ошибка: invalid types ‘int[int]’ for array subscript - C++
Всем доброго дня, после компиляции выводится ошибка, которая меня вводит в ступор. #include &quot;blitz.h&quot; double dummy11 = 0.0; Array...

В чем разница между long int и short int - C++
Извините если вопрос нубский, но я ни как не могу понять смысл long int и short int. Например с unsingned все ясно. Один байт в int...

std::filesystem && std::asio и пр - C++
Пытался найти хоть какие-то сроки включения всего этого в стандарт (так же ожидается lexical_cast, any, string_algo и т.д.) и вообщем везде...

stack overflow in C++ - C++
#include&lt;iostream&gt; #include&lt;cmath&gt; using namespace std; int main() { int n,i,n1,j,a1,b1; double n2; bool a; bool b; ...

C++ STL Создать контейнер (Stack) - C++
1. Создать объект-контейнер и заполнить его данными, тип stack 2. Просмотреть контейнер. 3. Изменить контейнер, удалив из него одни...

10
Kastaneda
Jesus loves me
Эксперт С++
4700 / 2904 / 239
Регистрация: 12.12.2009
Сообщений: 7,397
Записей в блоге: 2
Завершенные тесты: 1
31.03.2017, 16:28 #2
Думаю честным путем это никак не сделать, т.к.
Цитата Сообщение от hoggy Посмотреть сообщение
что stack_t и cstack_t - два принципиально разных типа,
которые друг о друге ничего не знают.
У меня еще вот так на rextester.com собралось (правда с варнингами)
C++
1
cstack_t cst(*reinterpret_cast<cstack_t*>(&st));
А мой g++ 4.9.3 ругается на
C++
1
std::cout << cst.top()<<std::endl;
Bash
1
2
3
4
5
6
7
8
tmp.cpp: In function ‘int main()’:
tmp.cpp:34:30: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
         std::cout << cst.top() << std::endl;
                              ^
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/iostream:39:0,
                 from tmp.cpp:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/ostream:602:5: note: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = item<const int>]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
Возможно компилятор с ума сходит, top() для не константного объекта возвращает reference, что есть const int& а нашем случае и, возможно, он не понимает как не константное может быть константным)
Цитата Сообщение от hoggy Посмотреть сообщение
вы бы пропустили такое через ревью?
Хз как оно еще может "стрельнуть", в любом случае оба решения попахивают, я бы не пропустил.

Добавлено через 2 минуты

Не по теме:

У меня как-то реджектнули код с placement new на ревью, т.к. placement new выглядит страшно и такой синтаксис мало кто знает.

0
hoggy
6763 / 2948 / 507
Регистрация: 15.11.2014
Сообщений: 6,624
Завершенные тесты: 1
31.03.2017, 17:05  [ТС] #3
Цитата Сообщение от Kastaneda Посмотреть сообщение
Хз как оно еще может "стрельнуть"
сейчас это работает лишь по одной причине:
строения объектов совпадают.

только это никто как бе не гарантируется.

Цитата Сообщение от Kastaneda Посмотреть сообщение
А мой g++ 4.9.3 ругается на
как нибудь можно было бы это на онлайн-компиляторе проверить?
0
Kastaneda
Jesus loves me
Эксперт С++
4700 / 2904 / 239
Регистрация: 12.12.2009
Сообщений: 7,397
Записей в блоге: 2
Завершенные тесты: 1
31.03.2017, 18:27 #4
Попробовал дома тоже на 4.9.3, но на Kubuntu, все нормально. На работе Gentoo, странно, не думаю, что поведение компилятора отличается в разных дистрибутивах Linux.
0
avgoor
957 / 591 / 129
Регистрация: 05.12.2015
Сообщений: 1,661
31.03.2017, 18:30 #5
Цитата Сообщение от hoggy Посмотреть сообщение
сейчас это работает лишь по одной причине:
строения объектов совпадают.
Можно определить оператор каста/конструктор в структуре item (как в прошлой теме).
Затем у микрософта в стеке определен _Get_container(). Просто создаем deque<citem_t> копированием из st._Get_container(). И конструируем cstack_t перемещением этого дека.

В gcc, т.к. в стеке контейнер по стандарту протектед, можно применить для доступа к контейнеру паттерн Паблик Морозов.
0
hoggy
6763 / 2948 / 507
Регистрация: 15.11.2014
Сообщений: 6,624
Завершенные тесты: 1
31.03.2017, 20:16  [ТС] #6
Цитата Сообщение от avgoor Посмотреть сообщение
Можно определить оператор каста/конструктор в структуре item (как в прошлой теме).
не поможет.

Цитата Сообщение от avgoor Посмотреть сообщение
у микрософта в стеке определен _Get_container()
не портируемо.

Цитата Сообщение от avgoor Посмотреть сообщение
Паблик Морозов
это точно никакое ревью не пройдет

я решил просто уходить со стека на какой нибудь вектор.
0
avgoor
957 / 591 / 129
Регистрация: 05.12.2015
Сообщений: 1,661
31.03.2017, 22:13 #7
Цитата Сообщение от hoggy Посмотреть сообщение
я решил просто уходить со стека на какой нибудь вектор
А почему не на дек, оберткой которого стек и является?
0
hoggy
6763 / 2948 / 507
Регистрация: 15.11.2014
Сообщений: 6,624
Завершенные тесты: 1
31.03.2017, 23:17  [ТС] #8
Цитата Сообщение от avgoor Посмотреть сообщение
А почему не на дек, оберткой которого стек и является?
дек наверна оверкилл, для стека
0
avgoor
957 / 591 / 129
Регистрация: 05.12.2015
Сообщений: 1,661
31.03.2017, 23:21 #9
Цитата Сообщение от hoggy Посмотреть сообщение
дек наверна оверкилл, для стека
Комитет считает иначе, ибо в стандарте стэк определен как:
C++
1
2
3
namespace std {
template <class T, class Container = deque<T> >
class stack {
Мне вообще непонятно, почему дек так редко используют.
0
hoggy
6763 / 2948 / 507
Регистрация: 15.11.2014
Сообщений: 6,624
Завершенные тесты: 1
31.03.2017, 23:37  [ТС] #10
Цитата Сообщение от avgoor Посмотреть сообщение
Комитет считает иначе, ибо в стандарте стэк определен как:
ну и какой профит от дека при вставке в задницу?
и взятия с задницы?
1
avgoor
957 / 591 / 129
Регистрация: 05.12.2015
Сообщений: 1,661
31.03.2017, 23:43 #11
hoggy, Профит в том, что память там выделяется порциями по мере надобности и при выделении ничего никуда не копируется, как при использовании вектора. А что он двусторонний - так отличия от односторонней реализации - минимальные (лишняя операция сложения).
2
31.03.2017, 23:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.03.2017, 23:43
Привет! Вот еще темы с ответами:

Run-Time Check Failure #2 - Stack around the variable 'MX' was corrupted. - C++
Решаю задачу. Вот код: #include &lt;iostream&gt; using namespace std; int main () { int S; long long MX; for (int...

Run-Time Check Failure #2 - Stack around the variable 'A' was corrupted - C++
#include &lt;iostream&gt; #include &lt;iomanip&gt; using namespace std; int main() { setlocale(LC_ALL,&quot;Russian&quot;); const int n=50; int...

Run-Time Check Failure #2 - Stack around the variable 'support_points_1' was corrupted - C++
Ошибка вылетает на статический массив после завершения работы функции. Вроде как выход за границы массива.. но никаких ошибок, до...

Как привести строку типа TCHAR в int - C++
Есть строка TCHAR tmp; в ней записано число, нужно вытащить это число и записать его в переменную типа Int. Раньше я использовал для этого...


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

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

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