Aktywne Wpisy
wyjek +475
mirko_anonim +17
✨️ Obserwuj #mirkoanonim
Mirki, jesteśmy razem z dziewczyną 8 lat, oststnio zapytała co myślę o miesiącu przerwy i przyzwolenia obu stron na randkowanie i skok w bok, żeby znowu poczuć dreszczyk emocji przy poznawaniu nowych osób. Co myślicie na ten temat? Mam mocno mieszane uczucia. #seks #zwiazki #milosc
─────────────────────
· Akcje: Odpowiedz
Mirki, jesteśmy razem z dziewczyną 8 lat, oststnio zapytała co myślę o miesiącu przerwy i przyzwolenia obu stron na randkowanie i skok w bok, żeby znowu poczuć dreszczyk emocji przy poznawaniu nowych osób. Co myślicie na ten temat? Mam mocno mieszane uczucia. #seks #zwiazki #milosc
─────────────────────
· Akcje: Odpowiedz
T1
, w jakiś sposób "zapamiętać" typ przyjęty przez konstruktor, a następnie w innej funkcji sprawdzić, czy inny podany typT2
==
T1
.Spróbowałem zrobić to w ten sposób:
struct Foo {
std::size_t type;
template
Foo(T value) : type(typeid(T).hash_code()) {}
``````
template
const bool is_same() {
return typeid(T).hash_code() == type;
}
};
``````
Foo bar(3.14f);
const bool same = bar.is_same();
std::cout << same; // 1
To działa poprawnie(pomijając
const
, botypeid
ma z tym problem), ale czy nie dałoby się tego wykonać lepiej, np. używającconstexpr
, aby identyfikatory typów(typeid(T).hash_code()
), nawet tylko tych fundamentalnych, były wprowadzane statycznie, na etapie kompilacji(czyli nie za pomocątypeid
, ale jakoś inaczej), a nie dopiero w trakcie działania programu?#programowanie #cpp + specjaliści: @KrzaQ2, @lionbest ( ͡° ͜ʖ ͡°)
int a;
std::cin >> a;
Foo &bar = *(a == 1 ? new Foo(3.14f) : new Foo(23));
typeid(T).hash_code()
było rozwiązywane na etapie kompilacji, ale z tego co wiem,typeid
jest zawszerun-time
.@KrzaQ2: myślałem czy da się zaimplementować coś w rodzaju boost::any bez użycia
typeid
.Na przykład tak:
struct Any {
char value[8]; // oczywiscie tu powinna byc jakas dedukcja najwiekszego mozliwego rozmiaru prymitywnego typu
template
Any(T v) {
*((T *)&value) = v;
}
``````
template
const T get() {
return *((T *)&value);
boost::
/std::variant
variant
, bo przecież wtedy nie będę w stanie tego użyć wstd::vector
ze lub innym kontenerze, jeśli chcę, abyAny
mógł przechowywać dowolny typ.Załóżmy taką sytuację:
using Settings = std::map;
Settings settings{
{ "foo", 3.14f }, // float (4)
{ "bar", 6.28 }, // double (8)
{ "xyz", "hello" } // const char * (8)
}
try {
const auto s = settings["xyz"].get();
}
catch (... ex) {}
typeid
:struct Any {
static constexpr int INVALID_TYPE = 0;
char value[8];
std::size_t type;
``````
template
Any(T v) : type(typeid(T).hash_code()) {
*((T *)&value) = v;
}
``````
template
const T get() {
if (typeid(T).hash_code() != type)
throw INVALID_TYPE;
``````
return *((T *)&value);
}
};
``````
Any foo(3.14f);
``````
try {
const auto value = foo.get();
} catch (...) {}
constexpr
powinny być do zrobienia: http://melpon.org/wandbox/permlink/wQI0LyRaWpXgI37Wstatic_assert(x.get() == 42);
, ale nie dałbym tego na produkcję bez gruntownego code review (którego by nie przeszło bo imo dość brzydkie, chociaż działa...)static types
?@5z7k9: Od C++11 jest do tego typeindex, bo sam hashcode() ci nie wystarczy (może się okazać że dwie mają taki sam), ale fakt faktem nie da się tego zainicjalizować jako constexpr czyli
constexpr Foo bar(3.14f);
nie zadziała.
Generalnie
typeid(T)
nigdy nie będzie constexpr, nie da się tego tak zaimplementować, no chyba że ograniczaszconstexpr
odpada ;) (no bo jak?)Any
, właśnie według tego counter patternu: http://melpon.org/wandbox/permlink/8zd6MLuavTHCkOaNCo najlepsze, wystarczy
-O1
i gcc już na etapie kompilacji wie, czy typy się zgadzają(żadnecmp
nie pojawia się w pliku wynikowym, również jeśli typy się zgadzają). Link dogodbolt
a: https://godbolt.org/g/Xr7BYLPS: W tym wypadku nie da się zrobić
static_assert
, ale C++ uczę się odDokładnie mi o ten sposób chodziło. Lecz tutaj nie możesz założyć że inne pliki C++ będą miały tą samą kolejność typów. Po za tym to wyższa magia i nie działa na wszystkich kompilatorach tak samo i ciężko powiedzieć czy to nie precyzyjność standardu czy bugi w kompilatorach.