#include <iostream>
#include <vector>
class ConcreteStream1 {
private:
friend class IStream;
inline void foo() {
std::cout << "ConcreteStream1::foo" << std::endl;
}
};
class ConcreteStream2 {
private:
friend class IStream;
inline void foo() {
std::cout << "ConcreteStream2::foo" << std::endl;
}
};
class IStream {
public:
IStream(ConcreteStream1&& concreteStream1)
: streamType(StreamType::ConcreteStream1),
storage(Storage(std::forward<ConcreteStream1>(concreteStream1))) {}
IStream(ConcreteStream2&& concreteStream2)
: streamType(StreamType::ConcreteStream2),
storage(Storage(std::forward<ConcreteStream2>(concreteStream2))) {}
inline void foo() {
switch (streamType) {
case StreamType::ConcreteStream1:
storage.concreteStream1.foo();
break;
case StreamType::ConcreteStream2:
storage.concreteStream2.foo();
break;
}
}
private:
enum class StreamType {
ConcreteStream1,
ConcreteStream2,
};
private:
StreamType streamType;
union Storage{
Storage(ConcreteStream1&& concreteStream1)
: concreteStream1(std::move(concreteStream1)) {}
Storage(ConcreteStream2&& concreteStream2)
: concreteStream2(std::move(concreteStream2)) {}
ConcreteStream1 concreteStream1;
ConcreteStream2 concreteStream2;
} storage;
};
int main() {
std::vector<IStream> streams = { ConcreteStream1{}, ConcreteStream2{} };
streams[0].foo();
streams[1].foo();
return 0;
}
Программирование. Заметки.
понедельник, 14 июля 2025 г.
Полиморфизм на основе стирания типа
воскресенье, 13 июля 2025 г.
Динамический полиморфизм vs Статический полиморфизм
Динамический полиморфизм
#include <iostream>
class IStream {
public:
virtual ~IStream() = default;
virtual void foo() = 0;
};
class Stream : public IStream {
public:
void foo() override {
std::cout << "Stream::foo" << std::endl;
}
};
int main() {
IStream* stream = new Stream;
stream->foo();
return 0;
}
Статический полиморфизм
#include <iostream>
template<typename Stream>
class IStream : public Stream {
public:
inline void foo() {
return static_cast<Stream*>(this)->foo();
}
};
class Stream {
private:
friend class IStream<Stream>;
inline void foo() {
std::cout << "Stream::foo" << std::endl;
}
};
int main() {
IStream<Stream> stream;
stream.foo();
return 0;
}
вторник, 9 января 2024 г.
Статический полиморфизм в С++
#include <iostream>
// ------------------------ interface ------------------------
template<typename T>
struct IMeta
{
inline void foo() { return static_cast<T*>(this)->_foo(); }
};
template<typename T>
struct IPayload
{
inline void bar() { return static_cast<T*>(this)->_bar(); }
};
template<typename T>
struct IStream : public T, public IPayload<IStream<T>>, public IMeta<IStream<T>>
{
inline void baz() { return static_cast<T*>(this)->_baz(); }
};
// ------------------------ implementation ------------------------
template<typename T>
class Meta
{
friend class IMeta<IStream<T>>;
inline void _foo()
{
std::cout << "Meta::_foo::a = " << static_cast<T*>(this)->a << std::endl;
}
};
template<typename T>
class Payload
{
friend class IPayload<IStream<T>>;
inline void _bar()
{
std::cout << "Payload::_bar::a = " << static_cast<T*>(this)->a << std::endl;
}
};
class Stream : public Meta<Stream>, public Payload<Stream>
{
friend class IStream<Stream>;
friend class Meta<Stream>;
friend class Payload<Stream>;
uint64_t a = 3;
inline void _baz()
{
std::cout << "Stream::_baz::a = " << a << std::endl;
}
};
// ------------------------ usage ------------------------
int main()
{
IStream<Stream> stream;
stream.foo();
stream.bar();
stream.baz();
return 0;
}
вторник, 2 января 2024 г.
С++17: автоопределение в runtime потока вызова для функции
#include <iostream>
#include <thread>
void foo(unsigned char *data)
{
thread_local std::thread::id currentId(std::this_thread::get_id());
static std::thread::id id1(std::this_thread::get_id());
if (currentId == id1)
{
std::cout << "Thread1" << std::endl;
return;
}
static std::thread::id id2(std::this_thread::get_id());
if (currentId == id2)
{
std::cout << "Thread2" << std::endl;
return;
}
throw std::runtime_error("Thread is not processed!");
}
int main()
{
unsigned char *ptr;
std::thread thread1([&] { foo(ptr); });
std::thread thread2([&] { foo(ptr); });
//std::thread thread3([&] { foo(ptr); }); // will be an exception
thread1.join();
thread2.join();
//thread3.join();
return 0;
}
Перегруженный макрос
https://ideone.com/Kp59hv
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
/*
"Variadic macros tricks"
https://w...content-available-to-author-only...t.co/2014/11/25/variadic-macros-tricks/
"Is it possible to iterate over arguments in variadic macros?"
https://stackoverflow.com/questions/1872220/is-it-possible-to-iterate-over-arguments-in-variadic-macros/
*/
#define _GET_OVERRIDE(ARG_1, ARG_2, ARG_3, ACTION, ...) ACTION
#define MALLOC(pMem) \
( \
{ \
pMem = malloc(sizeof(*pMem)); \
pMem ? 0 : 1; \
} \
)
#define MALLOC_1(ARG_1, ...) MALLOC(ARG_1)
#define MALLOC_2(ARG_1, ...) MALLOC(ARG_1) | MALLOC_1(__VA_ARGS__)
#define MALLOC_3(ARG_1, ...) MALLOC(ARG_1) | MALLOC_2(__VA_ARGS__)
/* with return value */
#define MULTI_MALLOC(...) _GET_OVERRIDE(__VA_ARGS__, MALLOC_3, MALLOC_2, MALLOC_1)(__VA_ARGS__)
#define FREE(pMem) \
{ \
free(pMem); \
pMem = NULL; \
}
#define FREE_1(ARG_1, ...) FREE(ARG_1)
#define FREE_2(ARG_1, ...) FREE(ARG_1) FREE_1(__VA_ARGS__)
#define FREE_3(ARG_1, ...) FREE(ARG_1) FREE_2(__VA_ARGS__)
/* without return value */
#define MULTI_FREE(...) _GET_OVERRIDE(__VA_ARGS__, FREE_3, FREE_2, FREE_1)(__VA_ARGS__)
int main(void)
{
uint16_t *pnShort = NULL;
uint32_t *pnInt = NULL;
uint64_t *pnLong = NULL;
printf("start: %p, %p, %p\n", pnShort, pnInt, pnLong);
if ( MULTI_MALLOC(pnShort, pnInt, pnLong) ) { return 1; }
printf("3 args: %p, %p, %p\n", pnShort, pnInt, pnLong);
MULTI_FREE(pnShort, pnInt, pnLong);
if ( MULTI_MALLOC(pnShort, pnInt) ) { return 1; }
printf("2 args: %p, %p, %p\n", pnShort, pnInt, pnLong);
MULTI_FREE(pnShort, pnInt);
if ( MULTI_MALLOC(pnShort) ) { return 1; }
printf("1 arg: %p, %p, %p\n", pnShort, pnInt, pnLong);
MULTI_FREE(pnShort);
printf("finish: %p, %p, %p\n", pnShort, pnInt, pnLong);
return 0;
Бен Клеменс "Язык С в XXI веке" гл.10 "Улучшенная структура" параграф "Векторизация функции" стр.218.пятница, 27 мая 2022 г.
Вывод на экран значения числа в битовом виде в Си
#include <stdio.h
#include <stdint.h
#include <limits.h
#define BIT_PRINT(VALUE) \
{ \
for(int i = sizeof(VALUE) * CHAR_BIT - 1; i >= 0; --i) \
{ \
printf("%c", ((VALUE) & (1LU << i)) ? '1' : '0'); \
} \
printf("\n"); \
}
#define BIT8_PRINT(VALUE) BIT_PRINT((uint8_t )VALUE)
#define BIT16_PRINT(VALUE) BIT_PRINT((uint16_t)VALUE)
#define BIT32_PRINT(VALUE) BIT_PRINT((uint32_t)VALUE)
#define BIT64_PRINT(VALUE) BIT_PRINT((uint64_t)VALUE)
int main()
{
BIT8_PRINT(0x03);
BIT16_PRINT(0x03);
BIT32_PRINT(0x03);
BIT64_PRINT(0x03);
return 0;
}среда, 22 мая 2019 г.
Эзотерический синтаксис С
#include <stdio.h>
int (*foo(int (*i)[]))[]
{
printf("Foo()\n");
return i;
}
int main(void)
{
int (*(*F[])(int (*)[]))[] = { &foo };
(*F)(NULL);
return 0;
}
Подписаться на:
Комментарии (Atom)