#include <iostream>
#include <concepts>
class A {};
class AA : public A {
public:
static constexpr const char* AData = "AA";
};
class B {};
class BB : public B {
public:
static constexpr const char* BData = "BB";
};
// Через концепции
template <class T>
concept ASon = std::derived_from<T, A>;
template <class T>
concept BSon = std::derived_from<T, B>;
template <ASon T>
void foo(const T&) {
std::cout << T::AData << std::endl;
}
template <BSon T>
void foo(const T&) {
std::cout << T::BData << std::endl;
}
template <class T> constexpr bool FALSE_V = false;
// Через if consexpr
template <class T>
void bar(const T&) {
if constexpr (std::is_base_of_v<A, T>) {
std::cout << T::AData << std::endl;
} else if constexpr (std::is_base_of_v<B, T>) {
std::cout << T::BData << std::endl;
} else {
static_assert(FALSE_V<T>);
}
}
int main()
{
foo(AA());
foo(BB());
bar(AA());
bar(BB());
return 0;
}
#include <utility>
#include <iostream>
class Cursor {
public:
Cursor(int aShape) noexcept : fShape(aShape) {}
int shape() const noexcept { return fShape; }
private:
int fShape;
};
template <typename T, typename TFactory>
class Lazy {
public:
Lazy(TFactory&& x) : factory(std::move(x)) {}
Lazy(const TFactory& x) : factory(x) {}
T operator()() const { return factory(); }
private:
mutable TFactory factory;
};
template <typename T, typename TFactory>
inline auto lazy(TFactory&& factory)
{
return Lazy<T, std::decay_t<TFactory>>(std::forward<TFactory>(factory));
}
int main()
{
auto arrow = lazy<Cursor>([] { return Cursor(42); } );
std::cout << arrow().shape() << '\n';
return 0;
}
// Пишет вот такой код
class A implements Serializable { }
class B extends A {}
// А читает вот такой
class A implements Serializable { }
class AHalf extends A {
private void readObjectNoData() throws ObjectStreamException {}
}
class B extends AHalf {}
"hello"
имеет тип const char[]
. Как дополнительную подсказку, что даже если система (скажем, DOS) не имеет разделения памяти по типам и позволяет менять такие литералы — Windows имеет и не позволяет.char hello1[] = "hello"; // массив длины 6, в изменяемом сегменте или стеке,
// данные скопированы из литерала, который
// сидит в неизменяемом сегменте
const char* hello2 = "hello"; // указатель направлен прямо на литерал,
// и попытка изменить его под Windows — вылет
char* hello1 = const_cast<char*>("hello");
char* hello2 = const_cast<char*>("hello");
hello1[1] = 'U'; // hello2 = "hUllo" в системах вроде DOS, где не вылетит
{ char* buf = calloc(n, sizeof(char)); // Ради чего я создал блок — ставлю в той же строке
snprintf(buf, n, some_shit);
strcpy(dest, buf);
free(buf);
}
{ std::ofstream os(fname);
os << someData;
} // Тут файл закрыт