LINUX.ORG.RU

306
Всего сообщений: 3953

способы инициализации классов

struct Test
{
    Test(int a, int b)
    : a_(a), b_(b) {}

    int a_;
    int b_;
};

Test ch1 = Test(1, 2);  // #1
Test ch3 = Test({1, 2}); // #2
Test ch4 = Test{1, 2};   // #3

Test ch5(1, 2);  // #4
Test ch6({1, 2});  // #5
Test ch7{1, 2};   // #6

Test ch8 = {1, 2}; // #7

Ребят, просветите, есть ли какая-то разница между инициализацией с разными скобками? Почему это всё работает?

Насколько я понимаю, у 4-5-6 не происходит копирование временного объекта.

(в контексте С++14)

 

lvmuser ()

Шаблон не хочет автоматически выводить тип, как бы его заставить?

При использовании лямбд и function в параметре шаблонизированной функции, оно почему то не хочет автоматически выводить тип. Для примера:

template <class T>
void test(const std::function<void(T ii)> &task) {
    task(5);
}

...

    test<int>([&](int ii) { // так компилит
        qDebug() << ii;  });

    test([&](int ii) { // так не компилит
        qDebug() << ii;  });

no matching function for call to ‘test(main()::<lambda(int)>)’

candidate: ‘template<class T> void test(const std::function<void(T)>&)’
    6 | void test(const std::function<void(T ii)> &task) {
      |      ^~~~
template argument deduction/substitution failed:
‘main()::<lambda(int)>’ is not derived from ‘const std::function<void(T)>’

Если весь тип function заменить на auto, то компилит (c++20):

void test(const auto &task) {
    task(5);
}
Но так не хотелось бы, не наглядно. И явно каждый раз прописывать тип шаблон это много избыточности при многоэтажных типах.

Так же при использовании auto не позволяет сделать параметр со значением по умолчанию

void test(const auto& task = nullptr) {
    if (task) // error: could not convert ‘task’ from ‘const main()::<lambda(int)>’ to ‘bool’
        task(5);
}

Что нужно в шаблоне дописать, что бы все же можно было прописать тип function, а после вызывать без явного указания типов шаблона?

 ,

victor79 ()

Кто-нибудь пробовал build2?

Система сборки + автоматизированного тестирования + пакетный менеджер. Аналог Rust cargo для C++:

https://www.youtube.com/watch?v=Nni2Qu2WitY

 

seiken ()

вакансия разработчик драйверов ядра Linux

Разработчик драйверов ядра LINUX 140-220 т.р. Москва, 10 минут пешком от ст.м. Динамо, м. Белорусская Офис, полная занятость

Компания разрабатывает встроенные средства обеспечения доверия и безопасности. Амбициозные проекты и серьезный портфель заказов.

Условия: -трудоустройство по ТК, белая зп -гибкое начало рабочего дня -возможен вариант частичной удалёнки -работа в небольшой сплочённой команде профессионалов -участие в реализации амбициозного и интересного проекта

Задачи: -разработка системных служб и приложений безопасности для , -работа на программных эмуляторах, , отладочных платах -разработка SDK для встроенных средств безопасности

Требуемые знания и навыки (>1 года): -разработка драйверов ядра Linux, программирование на уровне ядра -разработка встроенных систем, системного ПО -программирование на языке С, -Linux, , ,

-технический английский

Будет плюсом: -многопоточное программирование -практические навыки разработки дистрибутивов для встроенных систем с использованием -опыт программирования под мобильные ОС

контакты: @yusta2011 или почта: yusta2011@gmail.com

 , , ,

yusta2011 ()

Чем нынче модно редактировать & конпелять dll-ку для софтины, работающей под wine?

Всем привет. Сабж. Интересует нормальный IDE (vim не предлагать) и тулчейн, чтобы сидеть либо на онтопике, либо также внутри wine. Кодировка сорцов – cp1251.

 , ,

dimgel ()

Программист C++, QT, QML

Для сдельной работы требуется программист с++, qt, qml Необходимо перенести код из с, bash в c++. Код изначально написан для управления двумя моторами (через контроллер) и сканером штрихкодов. События которые необходимо пробросить в QML:

  1. Мотор работает
  2. Мотор остановился
  3. Мотор обучается
  4. Обучение мотора закончено
  5. Поломка
  6. Код считан
  7. Ошибка чтения кода

Исполнитель найден. Тему можно закрывать

 , , ,

shimajima ()

Адаптация кода для smart pointers

Привет всем.

Такая ситуация: хочу уйти от использования в коде raw pointers, к сожалению, многие функции Qt, с которой я должен работать, не принимают все эти *_ptr, а только указатели как они есть. Приходится обращаться при этом к методу get, что как я читал - плохо, чтобы получить искомое. Есть ли другой способ и умные указатели использовать и правильно преобразовывать их тип в нужный при передаче параметром?

Всем спасибо.

 , , ,

LongLiveUbuntu ()

Нарушение равенства при переводе строк

Любопытный фактец.

Если стандартную C++ стороку создавать из буфера с нулевыми символами на конце, нули будут учитываться в C++ классе, но, очевидно, что с т.з. C’шного представления строка заканчивается на нулевом символе. Т.о., существует такая строка Y, что она и равна созданной строке X, и одновременно неравна ей, в зависимости от того, используется ли C++ интерфейс или доступ к C’шной строке.

Вот пример:

#include <stdio.h>
#include <string>
#include <string.h>

int main()
{
    char str[5] = {'A', 'B', '\0', '\0', '\0'};
    auto s = std::string(str, 5);
    auto s2 = std::string("AB");
    
    // Strings are NOT equal!!!
    printf("std::strings equal? %d\n", s == s2);
    // But wait, they are equal
    printf("C-strings equal? %d\n", strcmp(s.c_str(), s2.c_str()) == 0);
}
std::strings equal? 0
C-strings equal? 1

Это нормально вообще?

 , ,

seiken ()

std::variant и двойной вызов деструктора

#include <iostream>
#include <variant>
using namespace std;

template<int nd>
class base {};

template<int nd>
class base_holder : public base<nd>{
public:
	 base_holder () {
		cout<<"new base_holder<"<<nd<<"> = "<<this<<endl;
	}
	~base_holder () {
		cout<<"del base_holder<"<<nd<<"> = "<<this<<endl;
	}
};

std::variant<base_holder<1>, base_holder<2>, base_holder<3>>
new_base_holder(int nd) {
	switch (nd) {
		case  1: return base_holder<1>();
		case  2: return base_holder<2>();
		case  3: return base_holder<3>();
		default: throw "";
	}
}

int main(int argc, char **argv){

	auto cc = new_base_holder(2);
	cout<<"tt"<<endl;
	
	return 0;
}

А на выходе:

new base_holder<2> = 0x7ffe8b143a77
del base_holder<2> = 0x7ffe8b143a77
tt
del base_holder<2> = 0x7ffe8b143aa6
Собственно, почему так происходит и ЧЯДНТ?

 , , ,

thunar ()

C++: Выделение массива памяти 1Гб в куче или в стеке?

Вот когда то давным давно, было не правильным выделять много памяти в стеке. Сначала даже не было динамических массивов.

Потом они появились, появились 64 битные системы и оперативка гигами, и виртуальные страницы памяти.

Т.е. по сути память сейчас можно выделять в стеке в равной степени как и в куче.

В стеке память выделяется быстрей, до поры, пока программа не начнет ее просить у операционки. И меньше дефрагментируется.

И вот для случаев когда известен необходимый объем, есть ли причины не выделять ее в стеке? И сколько можно?

10Мб..100Мб..1Гб..10Гб?

Операционка не подразумевается какая-то конкретная, все современные десктоповые вроде так умеют.

 

victor79 ()

Получить активную раскладку клавиатуры

Под иксами все просто:

int result;
auto display = XkbOpenDisplay( getenv( "DISPLAY" ), NULL, NULL, NULL, NULL, &result );
auto keyboard = XkbAllocKeyboard();
XkbGetNames( display, XkbGroupNamesMask, keyboard );
XkbStateRec state;
XkbGetState( display, XkbUseCoreKbd, &state );
keyboard->names->groups[state.group];

А как под Wayland? Можно ли под ним вообще как-то универсально получать информацию о раскладке, не зависимо от DM?

 , ,

SR_team ()

Оптимизация лаконичности вызова сортировки. Как бы так сделать, что бы все было красиво.

У меня в кастомном списке есть такой метод:

template <typename T>
class MyList {
    T *buf = nullptr;
    ...

    void sort(const function<bool(const T& v1, const T& v2)> &compare) {
        if (p_count > 1) std::sort(buf, buf+p_count, compare);
    }
который я могу использовать вот так:
    listData.sort([&](auto &it1, auto &it2) -> bool {
        return tmplLess(
                    it1.field1, it2.field1,
                    it1.field2, it2.field2,
                    it1.field3, it2.field3);
    });
(tmplLess: https://github.com/victorprogrammist/snippets/blob/main/templateCompare.h)

Т.е. все просто, вот только в использовании нужно дублировать поля. Можно попробовать использовать tuple следующим образом:

    template <typename ...Args>
    void sort(const function<std::tuple<Args...>(const T& v)> &fields) {
        sort([&](const T &v1, const T &v2) -> bool {
            return fields(v1) < fields(v2); });
    }

Но тогда уже не задействуются auto при написании использования, и следующий вызов генерит ошибку компиляции:

    listData.sort([&](auto &it) {
        return std::tuple(it.field1, it.field2, it.field3); });

template argument deduction/substitution failed:
note: ‘myFunc::<lambda(auto:45&)>’ is not derived from...

Как бы так сделать, что бы можно было сделать чуть лучше чем есть?

 ,

victor79 ()

проект на C++, имитирующий работу арм-процессора

Встретил такое: https://github.com/lucas-streanga/Processor-Project

Вкратце, программа принимает на вход инструкции

00001000000010000000001111111111 # move 16384 into register 0
00001010000000000000000000000000 # print r0
00000000000001000000000000000000 # add r0 and r0 and store in r0 + flags set
00001010000000000000000000000000 # print r0
00001000010010111000000000001000 # loop until carryover occurs
*
!

а выдает такое:

Loading program into memory...

***EXECUTION***

R0: 1023
R0: 2046
R0: 4092
...
R0: 1072693248
R0: 2145386496
R0: 4290772992
R0: 4286578688

End opcode recieved.
Execution ended.
Virtual Cycles used: 427

Я совсем не шарю в теме, но реально ли тут написать такие инструкции, которые выведут в консоль хеловорлд?

 , ,

lvmuser ()

Как узнать у long long числа количество цифр?

Вот пример задачи https://ibb.co/z2tcHxL вот мой код для int частично решается задача аналогично

#include <iostream>
#include <cstring>
int main()
{
int num=4000000;
char*word = new char[25];
sprintf(word,"%d",num);
std::cout « strlen(word);
}

 

bad_master ()

С++ ошибка компилятора в таком виде: баг или фича?

class A
{
 public:

    int data;
    virtual void method(){} //объявлена и определена
    virtual ~A(){}
};

class B : public A
{
public:
    virtual void method(); //объявлена, но ошибочно не определена
} b;

gcc 9.3.0

Вывод компилятора

/usr/bin/ld: test.o: in function `B::B()':
test.h:19: undefined reference to `vtable for B'
/usr/bin/ld: test.o: in function `B::~B()':
test.h:19: undefined reference to `vtable for B'

То есть, при отсутствии хотя бы одной виртуальной функции класса, компилятор «ругается» на отсутствие конструктора, деструктора, но НЕ самой отсутствующей функции

 ,

next_time ()

литературное тестирование (по следам Дональда нашего Кнута)

Асилив наполовину книжку Владимира Хорикова «Принципы юнит-тестирования» я что то вернулся к одной своей старой идее. Я занимаюсь разработкой всякого академического софта, и у нас юнит-тестирование делать не принято. С одной стороны проекты маленькие и без него как то можно жить, с другой его практически никто не умеет делать.

При этом документацию писать приходится, и коллеги жалуются что в моей документации мало примеров. Идея такая - раз в документации нужны примеры, то пусть эти примеры заодно играют роль тестов (всяких). Нужен doxygen наоборот, утилита которая из специально оформленной документации может выделить тесты, собрать их и запустить. Такие тесты все же лучше чем ничего.

Документация пишется разумеется в техе. Примеры оформляются в окружении verbatim, хотя можно выбрать какое то другое. В теховский документ добавляются специальные команды закомментированные для теха (начинающиеся с символа %), но влияющие на поведение утилиты тестирования.

  1. Может быть создано один или несколько файлов в которых накапливается код тестов по мере обработки теховской документации. Для создания файлов используется комбинация
%@> имена файлов через пробел 

созданные файлы могут быть активными (по умолчанию) или замороженными. Если файл активен, все что начинается с одиночного % или находится в окружении verbatim дублируется в этот файл. Для заморозки используется комбинация %@- имена файлов, для разморозки %@+ имена файлов, для закрытия файла %@. имена файлов. Для записи отдельной строки в файл или группу файлов (вне зависимости от их состояния) используется

%@(имена файлов) какой то код 

При этом в именах файлов можно использовать вайлдкарты а-ля шелл.

  1. если в окружение verbatim встречается комбинация
выражение --> результат

оно трактуется как тест. То есть в файлах с тестами, в зависимости от расширения, будет добавлен код вычисляющий выражение и сравнивающий его с результатом. В каждую строку теста в конец добавляется комментарий отсылающий к исходному теховскому файлу (имя и номер строки), если тест провален то выдается сообщение указывающее на строку в теховском файле откуда тест был взят.

  1. наверное можно вводить какие то макросы что бы переиспользовать подготовительный код тестов, команды для импорта модулей которые будут раскручиваться в зависимости от расширения файла в разный код и пр.

  2. Точно нужно будет настраивать как какие тесты собирать и запускать, аналогично через какой то вариант вроде %@$ … Ну и наверное для запуска тестов можно заюзать gnu make.

  3. Отдельная история с тестированием готовых приложений (небольших), на них ведь тоже пишется документация с примерами. В общем все то же самое но для запуска shell, при этом результаты сравниваются как строки?

Как то так. Cast @bugfixer, @pon4ik, @thunar, @Vit

 , , , ,

AntonI ()

Человекоинтуитивное сравнение имён файлов C++

Есть ли библиотека для такого? Что-то сходу не гуглится.

Алфавитное сравнение не предлагать: оно будет выдавать ложные результаты, например:

«12.txt» < «2.txt»

«alpha_10.txt» < «boo_3.txt»

ну и так далее

могу и сам, конечно, написать, но лень

И чтобы 2 раза не вставать: как тоже самое на bash сделать?

 ,

next_time ()

Машинное слово и его размер

Пытаюсь понять, что такое машинное слово.

Это вроде как размер регистра в процессоре. У каждой архитектуры он разный, например x86-64 он 64 бита.

Т.е. если я пишу int a = 123; - эти данные помещаются в регистр, размером 64 бита и не больше. Так?

И больше ничего о машинном слове знать не нужно? Просьба дополнить или поправить. (меня оно интересует в контексте С++)

 , ,

lvmuser ()

Дружба с глобальной функцией

Привет, вопрос элементарный, но что-то сообразить совсем не получается. Было примерно так (работало):

class Q {
   friend int main();
   Q() = default;
};

int main() {
   Q q;
}

Потом было добавлено namespace:

namespace NS {
class Q {
   friend int main();
   Q() = default;
};
} //NS

И теперь никак не удается назначить друга для Q из file scope. friend int main() не срабатывает (согласен), но также не помогает friend int ::main(), хотя на цппреференс есть пример:

friend class ::F; // friends the global F

Как правильно? Делать декларацию main в NS - не хочу. Компилятор выдает:

error: 'int main()' should have been declared inside '::'
   36 |  friend int ::main();

 

pavlick ()

Как скормить компилятору такую шляпу?

//g++  7.4.0

#pragma once
#include <iostream>
#include <list>
#include <vector>

#include <iterator>
template <typename T> class Sorts
{
public:
	std::list<T> arrayList;
	std::vector<T> bubbleArray,insertionArray,heapArray,shakeArray;
	std::vector<T> BubbleSort()
	{
		std::cout <<"Time to Bubble>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = bubbleArray.size();
		for (int i = 1; i < size; i++)
			for (int j = size-1; j >=i; j--)
				if (bubbleArray[j-1] > bubbleArray[j])
					swap(bubbleArray, j - 1, j);
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return bubbleArray;
	}
	std::vector<T> InsertionSort()
	{
		std::cout << "Time to Insertion>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = insertionArray.size();
		for (int i = 1; i < size; i++)
		{
			T tmp = insertionArray[i];
			int j = i;
			while (j > 0 && insertionArray[j - 1] > tmp)
			{
				insertionArray[j] = insertionArray[j - 1];
				j = j - 1;
			}
			insertionArray[j] = tmp;
		}
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return insertionArray;
	}
	void swap(std::vector<T> v, int n, int m)
	{
		T tmp = v[n];
		v[n] = v[m];
		v[m] = tmp;
	}
	std::vector<T> HeapSort()
	{
		std::cout << "Time to Heap>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = heapArray.size();
		for (int j = 0; j < size; j++)
		{
			for (int i = size / 2 - 1 - j / 2; i > -1; i--)
			{
				if (2 * i + 2 <= size - 1 - j)
				{
					if (heapArray[2 * i + 1] > heapArray[2 * i + 2])
					{
						if (heapArray[i] < heapArray[2 * i + 1])
						{
							swap(heapArray, i, 2 * i + 1);
						}
					}
					else
						if (heapArray[i] < heapArray[2 * i + 2])
						{
							swap(heapArray, i, 2 * i + 2);
						}
				}
				else
					if (2 * i + 1 <= size - 1 - j)
						if (heapArray[i] < heapArray[2 * i + 1])
							swap(heapArray, i, 2 * i + 1);
			}
			swap(heapArray, 0, size - 1 - j);
		}
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return heapArray;
	}
	std::vector<T> ShakeSort()
	{
		std::cout << "Time to Shake>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = shakeArray.size();
		int left = 0;
		int right = size - 1;
		do {
			for (int i = left; i < right; i++) {
				if (shakeArray[i] > shakeArray[i + 1])
					swap(shakeArray,i,i+1);
			}
			right--;
			for (int i = right; i > left; i--) {
				if (shakeArray[i] < shakeArray[i - 1])
					swap(shakeArray, i-1, i);
			}
			left++;
		} while (left < right);
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return shakeArray;
	}
	void PrintArray(int num)
	{
		switch (num)
		{
		case 0:
			for (std::list<T>::iterator it = arrayList.begin(); it != arrayList.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 1:
			for (std::vector<T>::iterator it = bubbleArray.begin(); it != bubbleArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 2:
			for (std::vector<T>::iterator it = shakeArray.begin(); it != shakeArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 3:
			for (std::vector<T>::iterator it = heapArray.begin(); it != heapArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 4:
			for (std::vector<T>::iterator it = insertionArray.begin(); it != insertionArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		default:
			break;
		
		}
		std::cout << std::endl;
	}
};



int main()
{
	const int iSize = 10;
	auto sort = new Sorts<int>();
	srand(time(0));
	for (int i = 0; i < iSize; i++)
	{
		sort->arrayList.push_back(rand() % iSize);
	}
	sort->BubbleSort();
	sort->ShakeSort();
	sort->HeapSort();
	sort->InsertionSort();

	sort->PrintArray(1);
	sort->PrintArray(2);
	sort->PrintArray(3);
	sort->PrintArray(4);
	return 0;
}

Ругаеца на итераторы

 , ,

bad_master ()