Здравствуйте, avovana, Вы писали:
A>Требуется реализовать функцию zip, которая соединяет элементы двух слайсов в слайс пар
Подозреваю, что хотели увидеть не просто перекладывание из контейнера в контейнер, а виртуальный контейнер, в духе std::ranges::zip_view (по возможности, без копирования).
Примерно так:
#include <iostream>
#include <algorithm>
#include <tuple>
#include <iterator>
#include <ranges>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <utility>
#include <cassert>
template< typename T >
struct container_traits
{
using iterator = decltype( std::begin( std::declval<T>() ) );
using value_type = typename std::iterator_traits< iterator >::value_type;
using reference_type = typename std::iterator_traits< iterator >::reference;
using container = T;
};
template< typename T >
struct container_traits< std::reference_wrapper<T> >
{
using iterator = typename container_traits<T&>::iterator ;
using value_type = typename container_traits<T&>::reference_type;
using reference_type = value_type;
using container = T&;
};
template< typename T1, typename T2 >
class zip : std::pair< typename container_traits<T1>::container ,
typename container_traits<T2>::container >
{
using base = std::pair< typename container_traits<T1>::container ,
typename container_traits<T2>::container >;
using _iterator_1 = typename container_traits<T1>::iterator;
using _iterator_2 = typename container_traits<T2>::iterator;
using _value_type_1 = typename container_traits<T1>::value_type;
using _value_type_2 = typename container_traits<T2>::value_type;
public:
using base::base;
using value_type = std::pair< _value_type_1, _value_type_2 >;
class iterator : public std::pair< _iterator_1, _iterator_2 >
// for C++14 and older:
// ,public std::iterator< std::input_iterator_tag, vlaue_type >
{
using base = std::pair< _iterator_1, _iterator_2 >;
public:
using base::base;
iterator operator++() { return { first++, second++ }; }
iterator operator++(int) {return { ++first, ++second }; }
bool operator == ( const iterator& r ) const { return static_cast<const base&>(*this) == r; }
bool operator != ( const iterator& r ) const { return static_cast<const base&>(*this) != r; }
vlaue_type operator*() const { return { *first, *second }; }
};
using const_iterator = iterator;
size_t size() const { return std::min( std::size(first), std::size(second) ); }
value_type operator[]( size_t index ) const { return { first[index], second[index] }; }
value_type at( size_t index ) const { return { first.at(index), second.at(index) }; }
iterator begin() const { return { first.begin(), second.begin() }; }
iterator end () const { return { first.end (), second.end () }; }
};
template< typename T1, typename T2 >
zip(T1,T2) -> zip<T1,T2>;
using namespace std;
int main()
{
auto i = zip( std::vector{1,2,3}, std::vector{"a"s, "b"s, "c"s} )[1];
assert( ( i==std::pair{2,"b"s} ) );
// support of conteiner with no 'operator[]'auto j= * std::begin( zip( std::list{1,2,3}, std::list{"a"s, "b"s, "c"s} ) );
assert( ( j==std::pair{1,"a"s} ) );
// TODO: support of std::initializer_list
// auto p = * std::begin( zip( {1,2,3}, {"a"s, "b"s, "c"s} ) );
// assert( ( p==std::pair{1,"a"s} ) );
// test 'size'
assert( zip( std::vector{1,2,3}, std::vector{"a"s, "b"s, "c"s, "d"s} ).size() == 3 );
// test for-each loopfor( auto i : zip( std::vector{1,2,3}, std::vector{"a"s, "b"s, "c"s} ) )
std::cout << i.first << " " << i.second << std::endl;
// modification via reference:
std::vector<int> a={1,2,3,4,};
std::vector<int> b={1,2,3,4,};
zip(std::ref(a),std::ref(b))[1] = std::pair{ 5,6 };
assert( a[1] == 5 );
assert( b[1] == 6 );
return 0;
}
Re[6]: Задача на наследование с вызовом виртуальных функций
BFE>>>>>По стандарту (11.10.4/4) должен быть вызван метод A::printFromDestructor(), значит ответ: ~A, а не ~B, как ошибочно указано в комментарии. P>>>>Это ж вроде UB — удаление объекта по указателю на базу, а деструктор не виртуальный? BFE>>>Хмм. Действительно σ>>Какой опыт кодинга на цепепе? BFE>29 лет. А что?
Не возраст, а опыт в C++.
Re[7]: Задача на наследование с вызовом виртуальных функций
Здравствуйте, σ, Вы писали:
BFE>>>>>>По стандарту (11.10.4/4) должен быть вызван метод A::printFromDestructor(), значит ответ: ~A, а не ~B, как ошибочно указано в комментарии. P>>>>>Это ж вроде UB — удаление объекта по указателю на базу, а деструктор не виртуальный? BFE>>>>Хмм. Действительно σ>>>Какой опыт кодинга на цепепе? BFE>>29 лет. А что? σ>Не возраст, а опыт в C++.
А это и есть опыт: начинал на MS-DOS + Borland Turbo C++. Но это С++, а на C я ещё перфоленты застал (это после Фортрана и перфокарт). Но к чему все эти вопросы?
И каждый день — без права на ошибку...
Re[8]: Задача на наследование с вызовом виртуальных функций
Здравствуйте, kaa.python, Вы писали:
KP>Недавно на собеседовании решал очень похожую, но с дополнительным наворотом в виде "аргументы 2 и 3 взаимозаменяемы" — надо заменять тот, что нашел первым на противоположный.
По sql сейчас почитал по запросам.
Такое придумал. Насколько правильно?
select firstname.user, sku.purchase from user, purchase // Показываю столбцы
where id.user=user_id.purchase // объединенные кросс join'ом. Показываю лишь те строки, у которых id из этих столбцов равны
and
purchase.date between 2021-02-01 and 2021-02-27 // причем покажу только строки в которых значение даты купленного товара из интервала
and
where not id.user in (select user_id.ban_list from ban_list) // уберу такие, у которых id.user из списка, который получил вложенным подзапросом
A>Тестовое задание.
A>В данной задаче будут рассматриваться 13-ти значные числа в тринадцатиричной системе исчисления(цифры 0,1,2,3,4,5,6,7,8,9,A,B,C) с ведущими нулями.
A>Например, ABA98859978C0, 6789110551234, 0000007000000
A>Назовем число красивым, если сумма его первых шести цифр равна сумме шести последних цифр.
A>Пример:
A>Число 0055237050A00 — красивое, так как 0+0+5+5+2+3 = 0+5+0+A+0+0
A>Число 1234AB988BABA — некрасивое, так как 1+2+3+4+A+B != 8+8+B+A+B+A
A>Задача:
A>написать программу на С/С++ печатающую в стандартный вывод количество 13-ти значных красивых чисел с ведущими нулями в тринадцатиричной системе исчисления.
A>В качестве решения должен быть предоставлено:
A>1) ответ — количество таких чисел. Ответ должен быть представлен в десятичной системе исчисления.
A>2) исходный код программы.
from functools import cache
nums = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
@cache
def num_ways(n, depth, numbers):
if n < 0:
return 0
if depth == 0:
return 1 if n == 0 else 0
ans = 0
for number in numbers:
ans += num_ways(n-number, depth-1, numbers)
return ans
count = 0
for s in range(0, 73):
cnt = num_ways(s, 6, nums)
print(s,' ', cnt)
count += cnt*cnt
print(count)
Здравствуйте, reversecode, Вы писали:
R>так и хочется посмотреть в глаза комитету R>что же это за уб по стандарту, если все существующие компиляторы выдают один и тот же результат
Не вижу ничего удивительного в том, что в некоторых частных случаях UB совпадает с интуитивно ожидаемым поведением.
Я бы поинтересовался почему не S* s = new(storage) S("hello world"); вместо последних двух строк и в чём разница с дальнейшим использованием s (слева) в s->s.
Re[12]: Задача на наследование с вызовом виртуальных функций
здесь надо углубляться в саму суть проблемы и почему по стандарту это уб?
это из той же серии почему до сих пор ++i + i++ уб ?
комитет не может определиться как обходить дерево?
и тогда на вопрос при собеседовании — что выведет тот код с не виртуальными деструкторами использующие виртуальные методы
вы вы как практикующий программист с пруфами на все существующие компилеры скажете ?
>from A >the end
хотя вопрос будет наверняка провокационным и задающий будет ожидать ответа — уб
и я в +100500 раз бы повторил, лавер с++ != программист с++
этот точно так же как гражданин страны не обязан знать наизусть все законы той страны где он проживает,
иначе юристы бы померли от голода
R>здесь надо углубляться в саму суть проблемы и почему по стандарту это уб?
Ответ очень простой: а почему должно быть не UB? "Потому что все известные мне реализации ведут себя одинаково" это не ответ.
Re[13]: Задача на наследование с вызовом виртуальных функций
Здравствуйте, reversecode, Вы писали:
R>здесь надо углубляться в саму суть проблемы и почему по стандарту это уб?
Потому, что после delete мы имеем объект частично разрушенный. После этого ничего разумного с таким объектом сделать не можно.
R>это из той же серии почему до сих пор ++i + i++ уб ?
Это потому, что ++i и i++ могут выполнятся параллельно. Теоретически (но это пока).
R>комитет не может определиться как обходить дерево?
Не в этом дело.
R>и тогда на вопрос при собеседовании — что выведет тот код с не виртуальными деструкторами использующие виртуальные методы R>вы вы как практикующий программист с пруфами на все существующие компилеры скажете ?
Да как обычно: этот код следует переписать, так как он не соответствует общепринятой практике. Любой инструмент проверки кода укажет, что деструктор в данном случае должен быть виртуальным.
>>from A >>the end R>хотя вопрос будет наверняка провокационным и задающий будет ожидать ответа — уб
Ну..., я сразу назвал код безумным.
R>и я в +100500 раз бы повторил, лавер с++ != программист с++ R>этот точно так же как гражданин страны не обязан знать наизусть все законы той страны где он проживает, R>иначе юристы бы померли от голода
Тут ведь как: незнание законов не освобождает от ответственности.
И каждый день — без права на ошибку...
Re[6]: Задача на наследование с вызовом виртуальных функций
Здравствуйте, Kolesiki, Вы писали:
K>Вы страшный человек! Кодить на сипипях, имея уже лет как 20 C#, это надо очень сильно себя не любить.
Ха! Текущий проект в котором я работаю (и который уже в эксплуатации), это переписывание с C# на С++. Это всё из-за того, что в MS не предполагают продлевать поддержку Windows CE. В результате огромное количество всякого встроенного будет переведено на Debian + QT.