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

C++

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

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

31.03.2017, 14:40. Просмотров 287. Ответов 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. Замечательно, то же самое... ошибка при...

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

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

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
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,491
Записей в блоге: 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
6813 / 3001 / 516
Регистрация: 15.11.2014
Сообщений: 6,794
Завершенные тесты: 1
31.03.2017, 17:05  [ТС] #3
Цитата Сообщение от Kastaneda Посмотреть сообщение
Хз как оно еще может "стрельнуть"
сейчас это работает лишь по одной причине:
строения объектов совпадают.

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

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

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

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

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

я решил просто уходить со стека на какой нибудь вектор.
0
avgoor
965 / 599 / 130
Регистрация: 05.12.2015
Сообщений: 1,682
31.03.2017, 22:13 #7
Цитата Сообщение от hoggy Посмотреть сообщение
я решил просто уходить со стека на какой нибудь вектор
А почему не на дек, оберткой которого стек и является?
0
hoggy
6813 / 3001 / 516
Регистрация: 15.11.2014
Сообщений: 6,794
Завершенные тесты: 1
31.03.2017, 23:17  [ТС] #8
Цитата Сообщение от avgoor Посмотреть сообщение
А почему не на дек, оберткой которого стек и является?
дек наверна оверкилл, для стека
0
avgoor
965 / 599 / 130
Регистрация: 05.12.2015
Сообщений: 1,682
31.03.2017, 23:21 #9
Цитата Сообщение от hoggy Посмотреть сообщение
дек наверна оверкилл, для стека
Комитет считает иначе, ибо в стандарте стэк определен как:
C++
1
2
3
namespace std {
template <class T, class Container = deque<T> >
class stack {
Мне вообще непонятно, почему дек так редко используют.
0
hoggy
6813 / 3001 / 516
Регистрация: 15.11.2014
Сообщений: 6,794
Завершенные тесты: 1
31.03.2017, 23:37  [ТС] #10
Цитата Сообщение от avgoor Посмотреть сообщение
Комитет считает иначе, ибо в стандарте стэк определен как:
ну и какой профит от дека при вставке в задницу?
и взятия с задницы?
1
avgoor
965 / 599 / 130
Регистрация: 05.12.2015
Сообщений: 1,682
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 '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 '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 '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.
Рейтинг@Mail.ru