Zde lze prohlédnout všech příspěvky uživatele. Jsou zde vidět pouze příspěvky z oblastí, do kterých máte přístup.
Stran1
#1
Vývoj / Re:C++20x std::sregex_iterator - skrátený zápis for loop-u
14. 06. 2022, 08:05:19 #2
Vývoj / Re:Conditional conformance v OOP
20. 02. 2021, 09:01:29
Jestli tomu dobře rozumím, tak to je jako koncepty v C++20. Což je v podstatě jen syntaxe pro SFINAE, který se v C++ používá od doby zavedení šablon.
#3
Vývoj / Re:C++ downcast this v předkovi na potomka
16. 02. 2021, 09:17:18
Ještě mě napadlo tam přidat CRTP prostředníka, aby to nemusel člověk všude psát.
Kód [Vybrat]
#include <string>
#include <typeinfo>
#include <iostream>
class Base {
protected:
Base(const std::type_info& derivedType) {
std::cout << "derived: " << derivedType.name() << std::endl;
}
};
template<typename Derived>
class BaseCrtp : public Base {
protected:
BaseCrtp() : Base(typeid(Derived)) {}
};
class Derived : public BaseCrtp<Derived> {
public:
Derived() {}
};
int main() {
Derived{};
return 0;
}
#4
Vývoj / Re:C++ downcast this v předkovi na potomka
15. 02. 2021, 16:29:23
Virtuální funkci z konstruktoru volat nejde. Potomek v tu dobu ani neexistuje. CRTP zase způsobí, že není jeden předek, ale jen šablona. Proč si teda nepředat potřebné parametry do konstruktoru, který bude protected? Například takto.
Kód [Vybrat]
#include <string>
#include <typeinfo>
#include <iostream>
class Base {
protected:
Base(const std::type_info& derivedType) {
std::cout << "derived: " << derivedType.name() << std::endl;
}
};
class Derived : public Base {
public:
Derived() : Base(typeid(Derived)) {}
};
int main() {
Derived{};
return 0;
}
#5
Vývoj / Re:C++ - template a constexpr pre dvojicu trieda - funkcia
12. 01. 2021, 16:23:35
Co třeba takto:
Místo různých názvů vytvořujících funkcí, a následného použití constexpr if, stačí odlišit vytvořující funkce pomocí parametru.
Variant se dá použít pro uložení tříd bez společného předka.
Kód [Vybrat]
#include <memory>
#include <string>
#include <variant>
struct A{};
struct B{};
struct C{};
template<typename T>
struct Tag{};
A makeGraph(const std::string& in, Tag<A>) {
return A{};
}
B makeGraph(const std::string& in, Tag<B>) {
return B{};
}
C makeGraph(const std::string& in, Tag<C>) {
return C{};
}
template<typename T>
std::variant<A, B, C> makeGraph(const std::string& in) {
return makeGraph(in, Tag<T>{});
}
int main() {
auto graph = makeGraph<A>({});
return 0;
};
Místo různých názvů vytvořujících funkcí, a následného použití constexpr if, stačí odlišit vytvořující funkce pomocí parametru.
Variant se dá použít pro uložení tříd bez společného předka.
#6
Vývoj / Re:C++ vyfiltrovanie položiek iterátoru a vrátenie ďalšieho iterátoru
12. 01. 2021, 15:58:43 #7
Vývoj / Re:Jake používáte prostředí pro vývoj (C++)_
29. 10. 2020, 08:19:48
Qt Creator, Visual Studio Code.
#8
Vývoj / Re:Discriminated unions v C++
26. 10. 2020, 13:29:04
Pro pořádek dodám i variantu s typy None a AnotherCurrency
Kód [Vybrat]
#include <variant>
#include <string>
#include <stdexcept>
#include <cassert>
#include <iostream>
enum class CurrencyTag {
Eur,
Usd,
Btc
};
template<CurrencyTag Tag>
struct CurrencyType {
double value = 0;
};
struct None {};
struct AnotherCurrency {
std::string name;
double value = 0;
};
template<CurrencyTag... Tags>
using CurrencyVariant = std::variant<None, AnotherCurrency, CurrencyType<Tags>...>;
using Currency = CurrencyVariant<CurrencyTag::Eur, CurrencyTag::Usd, CurrencyTag::Btc>;
constexpr double EUR_TO_USD = 1.1;
constexpr double BTC_TO_USD = 12000.;
struct ToUsd {
constexpr double operator()(CurrencyType<CurrencyTag::Eur> currency) const {
return currency.value * EUR_TO_USD;
}
constexpr double operator()(CurrencyType<CurrencyTag::Usd> currency) const {
return currency.value;
}
constexpr double operator()(CurrencyType<CurrencyTag::Btc> currency) const {
return currency.value * BTC_TO_USD;
}
template<typename T>
constexpr double operator()(T&& t) const {
throw std::runtime_error("Unsupported currency");
}
};
constexpr double toUsd(const Currency ¤cy) {
return std::visit(ToUsd{}, currency);
}
int main() {
assert(toUsd(CurrencyType<CurrencyTag::Btc>{1.}) == BTC_TO_USD);
try {
toUsd(None{});
} catch (const std::exception& ex) {
std::cerr << ex.what() << std::endl;
}
return 0;
}
#9
Vývoj / Re:Discriminated unions v C++
23. 10. 2020, 09:27:51
Myslím, že se tu trochu zaměňuje variant/union a pattern matching. Pattern matching v C++ skutečně není. Otagovat si nějaká data ale není problém.
Kód [Vybrat]
#include <variant>
enum class CurrencyTag {
Eur,
Usd,
Btc
};
template<CurrencyTag Tag>
struct CurrencyType {
double value;
};
template<CurrencyTag... Tags>
using CurrencyVariant = std::variant<CurrencyType<Tags>...>;
using Currency = CurrencyVariant<CurrencyTag::Eur, CurrencyTag::Usd, CurrencyTag::Btc>;
constexpr double EUR_TO_USD = 1/1.1;
constexpr double BTC_TO_USD = 12000.;
constexpr double toUsd(const Currency ¤cy) {
struct ToUsd {
constexpr double operator()(const CurrencyType<CurrencyTag::Eur>& currency) const {
return currency.value * EUR_TO_USD;
}
constexpr double operator()(const CurrencyType<CurrencyTag::Usd>& currency) const {
return currency.value;
}
constexpr double operator()(const CurrencyType<CurrencyTag::Btc>& currency) const {
return currency.value * BTC_TO_USD;
}
};
return std::visit(ToUsd{}, currency);
}
int main() {
static_assert(toUsd(CurrencyType<CurrencyTag::Btc>{1.}) == BTC_TO_USD);
return 0;
}
#10
Vývoj / Re:C++ funkcionálny typ
10. 09. 2020, 15:16:42
A co třeba takto:
Kód [Vybrat]
#include <vector>
#include <type_traits>
#include <cassert>
template<typename T, typename R = T>
constexpr auto mul_fun(T multiplier) {
return [multiplier](auto a) -> R {
return a * multiplier;
};
};
template<typename T, typename F>
constexpr auto map(F&& f, const std::vector<T>& v) {
std::vector<std::invoke_result_t<std::remove_cvref_t<F>, T>> ret;
ret.reserve(v.size());
std::transform(std::begin(v), std::end(v), std::back_inserter(ret), std::forward<F>(f));
return ret;
}
int main() {
constexpr auto f = mul_fun(5);
static_assert(f(3) == 15);
std::vector v1{1, 2, 3};
auto v2 = map(f, v1);
assert((v2 == std::vector{5, 10, 15}));
auto v3 = map(mul_fun<double>(2), v2);
assert((v3 == std::vector{10., 20., 30.}));
return 0;
}
Stran1