template <class T>
concept Printable = requires(T x) {
std::cout << x;
};
struct Class {
template<Printable Text>
Class& operator<<(const Text& text) {
cout << text << endl;
return *this;
}
template<uint8_t i>
struct Id {
constexpr static uint8_t id = i;
using SpecialPrint = void;
// какие-то элементы класса с методами
};
. . . . .
template <class T>
concept SpecialPrintable = requires {
typename T::SpecialPrint;
};
struct Class {
template<class Text>
Class& operator<<(const Text& text) {
cout << text << endl;
return *this;
}
template <SpecialPrintable Special>
Class& operator<<(const Special& text) {
specialPrint(text);
return *this;
}
template<uint8_t i>
void specialPrint(const Id<i>& text) {
cout << (int)i << endl;
}
};
template<uint8_t i>
struct Id {
constexpr static uint8_t id = i;
using SpecialPrint = void;
// какие-то элементы класса с методами
};
. . . . .
template<class T, class Dummy = void>
struct IsSpecPrintable { static constexpr bool value = false; };
template<class T>
struct IsSpecPrintable<T, typename T::SpecialPrint> { static constexpr bool value = true; };
struct Class {
template <class T>
Class& operator<<(const T& text)
{
if constexpr (IsSpecPrintable<T>::value) {
specialPrint(text);
} else {
normalPrint(text);
}
return *this;
}
template<class Text>
void normalPrint(const Text& text) {
cout << text << endl;
}
template<uint8_t i>
void specialPrint(const Id<i>& text) {
cout << (int)i << endl;
}
};
<<
для логгирования не очень подходит, т.к. вынуждает использовать конструкции типа: oss << "Error: " << strerror(err) << "(" << err << ")";
c = rand() % 2;
у тебя тут ошибка, c у тебя равно символу с кодом либо 0 либо 1,if (u == c)
c = rand() % 2+'0';
MyClass* arr = (MyClass*) operator new (sizeof(MyClass) * 10,
std::align_val_t(alignof(MyClass)));
. . .
operator delete(arr, std::align_val_t(alignof(MyClass)));
#include <iostream>
class MyClass {
private:
const int a;
public:
MyClass() = delete;
MyClass(MyClass&&) = delete;
MyClass(const MyClass&) = delete;
MyClass(int a) : a(a) {};
~MyClass() = default;
MyClass& operator=(MyClass&&) = delete;
MyClass& operator=(const MyClass&) = delete;
operator int() const { return a; }
};
template <class T>
class DynArray {
public:
static constexpr std::align_val_t ALIGNMENT { alignof(T) };
DynArray (size_t n)
: maxSize(n),
d((T*) operator new (sizeof(T) * n, ALIGNMENT )) {}
~DynArray() {
std::destroy_n(d, currSize);
operator delete(d, ALIGNMENT);
}
template <class... Args>
T& add(Args&&... args);
T& operator [] (size_t i) { return d[i]; }
const T& operator [] (size_t i) const { return d[i]; }
private:
size_t currSize = 0, maxSize = 0;
T* d;
};
template <class T> template <class... Args>
T& DynArray<T>::add(Args&&... args)
{
if (currSize >= maxSize)
throw std::logic_error("[DynArray::add] Overflow");
auto& where = d[currSize++];
new (&where) MyClass(std::forward<Args>(args)...);
return where;
}
int main() {
DynArray<MyClass> da(10);
for (int i = 0; i < 10; ++i) {
da.add(i);
}
// Что-то сделали с массивом
for (int i = 0; i < 10; ++i) {
std::cout << da[i] << '\n';
}
return 0;
}
std::deque<MyClass> dq;
for (int i = 0; i < 10; ++i) {
dq.emplace_back(i + 42);
}
// Что-то сделали с массивом
for (int i = 0; i < 10; ++i) {
std::cout << dq[i] << '\n';
}
index / X
, для второго - index % X
.std::vector<std::array>
.operator[]
на классе возвращает int*
на первый элемент в строке. То же, что у вас, только не надо никакого вспомогательного класса. Таким образом двойная индексация будет работать как надо. Но, как и во втором упомянутом вами примере, тут не будет проверки выхода за границы массива. mov eax, dword ptr [rax + 4*rcx]
в варианте с индексами используется инструкция mov eax, dword ptr [rax]
для указателей. Это самое "складывание с указателем массива" вообще не отдельная операция - а вариант адрессации в инструкции mov. Они могут вообще одинаковое количество тактов занимать, это надо мануал по конкретной архитектуре процессоров читать. template <const size_t c, const size_t b = c*c>
struct Sudoku_impl{
size_t s;
Sudoku_impl() {std::cout << b;}
};
int main(){
constexpr size_t x = 5;
Sudoku_impl<x> a;
return 0;
}
template <const size_t c>
using Sudoku = Sudoku_impl<c, c*c>;
template <const size_t cell>
class Sudoku {
private:
class Slot;
arr2<Slot, size> board;
public:
template <size_t size = cell*cell>
arr<Slot, size>& operator[](size_t index);
}
extern Logger logg
на Logger logg;
#include <iostream>
#include <fstream>
class Logger {
public:
Logger() {
openFile("Logger.txt");
}
~Logger() {
closeFile();
}
template<class T>
Logger& operator<<(const T& value) {
file << value;
std::cout << value;
return *this;
}
Logger& operator<<(std::ostream& (*manipulator) (std::ostream&)) {
file << manipulator;
std::cout << manipulator;
return *this;
}
void openFile(const char *path) {
file.open(path);
if(!file.is_open()) {
throw std::runtime_error("Failed to open 'Logger.txt'");
}
}
void closeFile() {
file.close();
}
private:
std::ofstream file;
};
Logger logger;
logger << 6 << " is six" << std::endl;
в разных отраслях для личного пользования.
<=
), белый - иначе.<
) циклов не образуют, то получившийся граф будет ациклическим и можно назначить всем вершинам какие-то числовые значения, удовлетворяющие условиям. Проблема может еще быть, что нет целых решений вроде 1== a < b < c == 2, но это можно потом проверить в топологической сортировке жадно назначая всем вершинам числа. Или противоречия вида 2==3. Тоже решается после получения компонент связности.case 1: {
cout << endl << "Введите модель:";
cin >> model;
cout << endl << "Введите прозводителя:";
cin >> producer;
cout << endl << "Введите цену:";
cin >> price;
cout << endl << "Введите год выхода:";
cin >> year;
Appliances appliances{ model,producer,price,year };
Appliances* pb = &appliances;
catalog.push_back(pb);
break;
}
target_link_libraries(Core Window Out)