» Poradna » Ostatní

Otazky k c++

 |   |  Microsoft Windows 10 Chrome 78.0.3879.0

1. Co pouzit ked chcem niekam dosadit premennu hociakeho typu. Viem ze C++ nema spolocneho predka pre vsetky typy tak ako napriklad C# (System.Object), ale existuje k tomu nejaka alternativa? cim sa to zvykne nahradit? Ak si odmyslime parametricky polymorfizmus a genericke parametre. Pointerom na void? Ci existuje aj nieco sofistikovanejsie.2. potrebujem typovu reprezentacia hociakej funkcie s hociakym poctom parametrov hociakeho typu a s navratovou hodnotou hociakehop typu. Napr:void wrapper(TYPOVA_REPREZENTACIA_VSETKYCH_FUNKCII funkcia) {...}TYPOVA_REPREZENTACIA_VSETKYCH_FUNKCII = ???Teda ked niekde zadam nazov toho typu ktory reprezentuje vsetky funkcie tak tam mozem dosadit hocico co sa da zavolat (funkciu, proceduru, metodu atd). Napr v JS je to predok vsetkych funkcii typ Function. Viem ze C++ nema objektovu hierarchiu (ak si ju sam nevytvorim) takze funkcie nemaju spolocneho predka, ale myslim ze by malo existovat nieco cim sa to da nahradit.3. ako zistim pocet parametrov funkcie? Podla moznosti by som chcel aj variantu v compile-time aj v runtime (aj ked ocakavam ze v runtime sa to asi zistit neda)

Odpovědi na otázku

 |   |  Microsoft Windows 10 Firefox 68.0
 |   |  Microsoft Windows 7 Firefox 68.0

nebo sem programujte.com

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Chrome 76.0.3809.132

Dakujem Vam pridal som to zatial na ten prvy web (som v praci a nemam vela casu) a vecer pridam aj na druhy.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Linux Chrome 73.0.3683.75

To je domácí úkol na C++17, že ano! Takže, k první otázce:std::any nebo std::variant; podle toho, jak málo / jak hodně toho o příslušné proměnné víš.Pokud jde o analogii s JavaScriptem, jedna možnost je představit si, jak bys implementoval hodně jednoduchý a neefektivní interpret JavaScriptu. Všechno by bylo dynamické, hodně by se nahlíželo do různých slovníků, typy a hodnoty parametrů by se kontrolovaly během run-time atd.Jenže předpokládám, že tohle^^^ není cílem domácího úkolu; cílem je implementovat polymorfní reprezentaci jakékoliv funkce v C++ způsobem co nejbližším C++. Proto JavaScript není zrovna vhodná analogie pro tento případ.Inu, tady je příklad pro nakopnutí. Enjoy. Přeložit se dá třeba takhle (když se bude jmenovat anyfunction.c++):clang++ -std=c++17 anyfunction.c++ -Wall -Werror -Wextra -Wfatal-errors -march=native -O3 -o anyfunction#include <any>#include <cmath>#include <functional>#include <iostream>#include <memory>#include <string>#include <tuple>#include <type_traits>#include <vector>namespace {  // The abstract function implementation.// Disambiguation between container-based and variadic constructors.struct Tag {};// A non-templated ancestor of all arbitrary functions, callable using// a container of std::any. The container has to be ordered correctly to match// the underlying function's arguments. Templated subclasses must provide the// actual implementation. For arguments and results of a reference type,// std::reference_wrapper<> must be used to provide the reference and also// a reference result will be returned wrapped in a std::reference_wrapper.class AbstractAnyFunction { public:  template <class... Args>  std::any operator()(Args &&... args) {    return call(std::vector<std::any>{std::conditional_t<        std::is_reference_v<Args>,        std::reference_wrapper<std::remove_reference_t<Args>>, Args>(        std::forward<Args>(args))...});  }  template <class Container>  std::any operator()(Container &&args, Tag) {    return call(std::forward<Container>(args));  }  virtual ~AbstractAnyFunction() = default; private:  virtual std::any call(const std::vector<std::any> &args) & = 0;  virtual std::any call(std::vector<std::any> &&args) & = 0;  virtual std::any call(const std::vector<std::any> &args) const & = 0;  virtual std::any call(std::vector<std::any> &&args) const & = 0;  virtual std::any call(const std::vector<std::any> &args) && = 0;  virtual std::any call(std::vector<std::any> &&args) && = 0;};// Templated representation of an arbitrary function.template <class...>class AnyFunction;// Specialization that allows the template argument syntax from std::function.template <class Result, class... Args>class AnyFunction<Result(Args...)> : public AbstractAnyFunction { public:  // Constructor that initializes the internal std::function with whatever can  // be assigned to it.  template <class Function>  AnyFunction(Function &&function)      : function_(std::forward<Function>(function)) {}  // Direct public call operators. This is for the case when the underlying  // function type happens to be known in advance, i.e., for a non-virtual case.  template <class... ForwardedArgs>  Result operator()(ForwardedArgs &&... args) & {    return function_(std::forward<ForwardedArgs>(args)...);  }  template <class... ForwardedArgs>  Result operator()(ForwardedArgs &&... args) const & {    return function_(std::forward<ForwardedArgs>(args)...);  }  template <class... ForwardedArgs>  Result operator()(ForwardedArgs &&... args) && {    return std::move(function_)(std::forward<ForwardedArgs>(args)...);  } private:  // Implementation of the virtual interface that calls the function from  // a vector of std::any. This is overloaded for all 'this' types and argument  // types, mainly because virtual methods cannot be templated.  std::any call(const std::vector<std::any> &args) & override {    checkSize(args.size());    if constexpr (std::is_void_v<Result>) {      vectorCall(args, std::index_sequence_for<Args...>{});      return std::tuple<>{};    } else {      return vectorCall(args, std::index_sequence_for<Args...>{});    }  };  std::any call(std::vector<std::any> &&args) & override {    checkSize(args.size());    if constexpr (std::is_void_v<Result>) {      vectorCall(std::move(args), std::index_sequence_for<Args...>{});      return std::tuple<>{};    } else {      return vectorCall(std::move(args), std::index_sequence_for<Args...>{});    }  };  std::any call(const std::vector<std::any> &args) const & override {    checkSize(args.size());    if constexpr (std::is_void_v<Result>) {      vectorCall(args, std::index_sequence_for<Args...>{});      return std::tuple<>{};    } else {      return vectorCall(args, std::index_sequence_for<Args...>{});    }  };  std::any call(std::vector<std::any> &&args) const & override {    checkSize(args.size());    if constexpr (std::is_void_v<Result>) {      vectorCall(std::move(args), std::index_sequence_for<Args...>{});      return std::tuple<>{};    } else {      return vectorCall(std::move(args), std::index_sequence_for<Args...>{});    }  };  std::any call(const std::vector<std::any> &args) && override {    checkSize(args.size());    if constexpr (std::is_void_v<Result>) {      std::move(*this).template vectorCall(args,                                           std::index_sequence_for<Args...>{});      return std::tuple<>{};    } else {      return std::move(*this).template vectorCall(          args, std::index_sequence_for<Args...>{});    }  };  std::any call(std::vector<std::any> &&args) && override {    checkSize(args.size());    if constexpr (std::is_void_v<Result>) {      std::move(*this).template vectorCall(std::move(args),                                           std::index_sequence_for<Args...>{});      return std::tuple<>{};    } else {      return std::move(*this).template vectorCall(          std::move(args), std::index_sequence_for<Args...>{});    }  };  // Support for calling the internal function from a container of std::any  // instead of a variadic list of known arguments. This supports mainly the  // abstract case in which the function accepts a container of arguments.  template <class Container, std::size_t... Indices>  std::conditional_t<std::is_reference_v<Result>,                     std::reference_wrapper<std::remove_reference_t<Result>>,                     Result>  vectorCall(Container &&args, std::index_sequence<Indices...>) & {    return function_(        std::any_cast<std::conditional_t<            std::is_reference_v<Args>,            std::reference_wrapper<std::remove_reference_t<Args>>, Args>>(            std::forward<Container>(args)[Indices])...);  };  template <class Container, std::size_t... Indices>  std::conditional_t<std::is_reference_v<Result>,                     std::reference_wrapper<std::remove_reference_t<Result>>,                     Result>  vectorCall(Container &&args, std::index_sequence<Indices...>) const & {    return function_(        std::any_cast<std::conditional_t<            std::is_reference_v<Args>,            std::reference_wrapper<std::remove_reference_t<Args>>, Args>>(            std::forward<Container>(args)[Indices])...);  };  template <class Container, std::size_t... Indices>  std::conditional_t<std::is_reference_v<Result>,                     std::reference_wrapper<std::remove_reference_t<Result>>,                     Result>  vectorCall(Container &&args, std::index_sequence<Indices...>) && {    return std::move(function_)(        std::any_cast<std::conditional_t<            std::is_reference_v<Args>,            std::reference_wrapper<std::remove_reference_t<Args>>, Args>>(            std::forward<Container>(args)[Indices])...);  }; private:  // This stops all sorts of strange errors when the number of arguments  // mismatches. This can only happen during abstract (container-based) calls.  static void checkSize(std::size_t argSize) {    if (argSize != sizeof...(Args))      throw std::make_tuple(sizeof...(Args), argSize);  }  // The function itself.  std::function<Result(Args...)> function_;};// Specialization that allows construction based on std::function classes.template <template <class, class...> class Function, class Result,          class... Args>class AnyFunction<Function<Result(Args...)>>    : public AnyFunction<Result(Args...)> { public:  using AnyFunction<Result(Args...)>::AnyFunction;};// Specialization that allows construction based on plain function references.template <class Result, class... Args>class AnyFunction<Result (&)(Args...)> : public AnyFunction<Result(Args...)> { public:  AnyFunction<Result (&)(Args...)>(Result (&function)(Args...))      : AnyFunction<Result(Args...)>(            std::function<Result(Args...)>{&function}) {}};// Deduction guide for constructing the abstract function representation from// lambdas. A lambda is not an std::function; so the compiler needs a hint.template <class Lambda>AnyFunction(const Lambda &lambda)->AnyFunction<decltype(std::function{lambda})>;// Deduction guide for constructing the abstract function from plain old// function pointers.template <class Result, class... Args>AnyFunction(Result (*const function)(Args...))->AnyFunction<Result(Args...)>;// Deduction guide for constructing the abstract function from plain old// function references.template <class Result, class... Args>AnyFunction(Result (&function)(Args...))->AnyFunction<Result(Args...)>;}  // namespacenamespace {  // Just auxiliary bits and pieces.template <class Type>std::ostream &operatorWrapper(std::ostream &stream, Type type) {  return stream << type;}}  // namespaceint main() try {  // Abstract function created from a lambda.  AnyFunction sum{[](int a, int b) { return a + b; }};  // Abstract function created from a library function.  AnyFunction sine{static_cast<double (*)(double)>(&std::sin)};  // Abstract function accepting and returning a reference, created from an  // operator. The C++ syntax makes it hard to wrap an operator (more) directly.  AnyFunction print{&operatorWrapper<const std::string &>};  // Direct calls to sum(), sine() and print() with well-known arguments.  std::cout << sum(3, 4) << std::endl << sine(2) << std::endl;  print(std::cout, "blaaah") << std::endl << "blaaah" << std::endl;  // Pointing at sum(), sine() and print() from an abstract reference.  AbstractAnyFunction &f1{sum}, &f2{sine}, &f3{print};  // Calling sum() and sine() from abstract references. Arguments can still be  // used directly (if their types match), but the results type needs to be  // obtained from std::any.  std::cout << std::any_cast<int>(f1(4, 5)) << std::endl            << std::any_cast<double>(f2(1.0)) << std::endl;  // Calling print() through its abstarct reference. We need to be careful about  // input reference types as well as the output reference type and unwrap it  // accordingly (from std::any and then from std::reference_wrapper). Wrapping  // into std::reference_wrapper happens implicitly.  std::any_cast<std::reference_wrapper<std::ostream>>(      f3(std::cout, static_cast<const std::string &>("one more blaah")))          .get()      << std::endl;  std::any_cast<std::reference_wrapper<std::ostream>>(      f3(std::cout, static_cast<const std::string &>("and yet one more")))          .get()      << std::endl;  // Four functions with zero to three arguments that just print strings.  void (*const zero_void)(){+[]() { std::cout << "Nothing!" << std::endl; }};  void (*const one_void)(const char *){      +[](const char *text) { std::cout << text << std::endl; }};  void (*const two_void)(      const char *, const char *){+[](const char *text1, const char *text2) {    std::cout << text1 << ' ' << text2 << std::endl;  }};  void (*const three_void)(const char *, const char *, const char *){      +[](const char *text1, const char *text2, const char *text3) {        std::cout << text1 << ' ' << text2 << ' ' << text3 << std::endl;      }};  // Four functions with zero to three arguments that concatenate strings.  std::string (*const zero_string)(){      +[]() -> std::string { return "Nothing!"; }};  std::string (*const one_string)(const std::string &){      +[](const std::string &text) -> std::string { return text; }};  std::string (*const two_string)(const std::string &, const std::string &){      +[](const std::string &text1, const std::string &text2) -> std::string {        return text1 + ' ' + text2;      }};  std::string (*const three_string)(const std::string &, const std::string &,                                    const std::string &){      +[](const std::string &text1, const std::string &text2,          const std::string &text3) -> std::string {        return text1 + ' ' + text2 + ' ' + text3;      }};  // A vector of abstract functions void(const char*...), with 0 to 3 arguments.  std::vector<std::unique_ptr<AbstractAnyFunction>> void_functions;  void_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*zero_void)>>(*zero_void));  void_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*one_void)>>(*one_void));  void_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*two_void)>>(*two_void));  void_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*three_void)>>(*three_void));  // A vector of abstract functions string(const string&...) with 0 to 3 args.  std::vector<std::unique_ptr<AbstractAnyFunction>> string_functions;  string_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*zero_string)>>(*zero_string));  string_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*one_string)>>(*one_string));  string_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*two_string)>>(*two_string));  string_functions.emplace_back(      std::make_unique<AnyFunction<decltype(*three_string)>>(*three_string));  // We iterate throught the vector of abstract functions and call each of them.  // We know (based on the way we created the vector) what number of arguments  // each function accepts. We increase the number of arguments accordingly.  size_t counter;  std::vector<std::string> args_storage;  // Strings used as arguments.  std::vector<std::any> args;  // std::any with std::reference_wwapper to above  args_storage.reserve(string_functions.size());  // no realloc on emplace_back!  args.reserve(string_functions.size());          // no realloc on emplace_back!  counter = 0;  for (auto &string_function : string_functions) {    std::cout << std::any_cast<std::string>((*string_function)(args, Tag{}))              << std::endl;    args_storage.emplace_back(std::string{"iteration "} +                              std::to_string(counter));    args.emplace_back(        std::reference_wrapper<const std::string>{args_storage[counter]});    ++counter;  }  // We repeat the same approach using the other four functions. The only  // difference is that we pass their arguments as a const char* (with a safe  // string backing store) instead of const string& and we do not care about the  // void return value (which is in fact represented by an empty std::tuple  // inside std::any; the reason being that std::any doesn't support incomplete  // types (e.g. void) in C++17; this will change in C++20.  args_storage.clear();  args.clear();  args_storage.reserve(void_functions.size());  // no realloc on emplace_back!  args.reserve(void_functions.size());          // no realloc on emplace_back!  counter = 0;  for (auto &void_function : void_functions) {    (*void_function)(args, Tag{});    args_storage.emplace_back(std::string{"iteration "} +                              std::to_string(counter));    args.emplace_back(args_storage[counter].c_str());    ++counter;  }  return 0;} catch (const std::tuple<size_t, size_t> &exception) {  // This handles mismatches in the number of arguments.  std::cerr << "Wrong function call; expectged " << std::get<0>(exception)            << " argument" << (std::get<0>(exception) == 1 ? "" : "s")            << ", got " << std::get<1>(exception) << ".";  return 1;} catch (const std::bad_any_cast &exception) {  // This handles types mismatches thrown from within std::any.  std::cerr << "Unknown bad std::any cast.";  return 2;}

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Linux Chrome 73.0.3683.75

No ale jak tady řádí malí zapšklí mínusáčci (kteří nejspíš ještě neviděli zdroják), to je svým způsobem vtipné.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Linux Chrome 76.0.3809.132

No jo. Tak fakt ještě nikdy neviděli zdroják. Hned jsem si to myslel. A teď se marně durdí a durdí.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Microsoft Windows 10 Firefox 69.0

Nic proti, ale priste ten kod radeji postni na https://pastebin.com a sem hod link

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Android Chrome 76.0

Spíš by si příště mohl použít mozek a nedávat kód sem do diskuze, ale nekam ho uploadnout a odkázat na něj.

Souhlasím  |  Nesouhlasím  |  Odpovědět
 |   |  Android Chrome 77.0

To já mozek nepoužívám. Jenom tak bez mozku něco nakódím, nacpu to do diskuze —> hotovo.

Souhlasím  |  Nesouhlasím  |  Odpovědět

Související témata: Void


Určitě si přečtěte

Windows 10 po čtyřech letech: Jsou populární, ale stále je to šílený kočkopes

Windows 10 po čtyřech letech: Jsou populární, ale stále je to šílený kočkopes

** Windows 10 tu jsou už čtyři roky, první verze dorazila 29. 7. 2015 ** Desítky měly nahradit neúspěšnou řadu Windows 8.x ** I po letech však systém budí emoce a zůstává kočkopsem

Jakub Čížek | 110

3D tisk pro naprosté zelenáče: Co vyrobíte na laciném stroji za pár tisíc korun

3D tisk pro naprosté zelenáče: Co vyrobíte na laciném stroji za pár tisíc korun

** Domácí 3D tisk je dnes už finančně dostupný prakticky všem ** Lacinou tiskárnu pořídíte za pár tisíc korun ** Jak vlastně tisk probíhá a jak navrhnout, co vytisknout

Jakub Čížek | 63

Raspberry Pi 4 Model B: Raketa za tisícikorunu, která utáhne dva monitory

Raspberry Pi 4 Model B: Raketa za tisícikorunu, která utáhne dva monitory

** Britové před pár dny představili nové Raspberry Pi 4 Model B ** Nový čipset má dost výkonu na dva HDMI monitory ** Za tisícovku získáte počítač na základní práci

Jakub Čížek | 80

Starý smartphone nemusí skončit v koši. 10 způsobů, jak ho ještě můžete využít

Starý smartphone nemusí skončit v koši. 10 způsobů, jak ho ještě můžete využít

** Co dělat s vysloužilým chytrým telefonem? Neházejte ho do koše! ** Našli jsme pro vás deset možností, jak ho prakticky využít ** I stará zařízení tak mohou být užitečná

Karel Kilián | 46

Je ta fotka černobílá, nebo barevná? Náš mozek realitu pouze odhaduje a vymýšlí si

Je ta fotka černobílá, nebo barevná? Náš mozek realitu pouze odhaduje a vymýšlí si

** Klasický počítač bezchybně zpracuje bit po bitu dat ** Mozek si realitu naopak spíše představuje a chybuje ** Teď se tím baví internet u další optické iluze

Jakub Čížek | 32

Biblická potopa Česka: Jak bychom dopadli, kdyby nás zatopil oceán

Biblická potopa Česka: Jak bychom dopadli, kdyby nás zatopil oceán

** Představte si biblickou potopu ** Nejprve zaniknou Děčín a Břeclav, pak i Brno a Praha ** Hlavním městem se stane Jihlava a zbytky Čechů přežijí na Kvildě

Jakub Čížek | 91



Aktuální číslo časopisu Computer

Megatest 18 grafických karet

Ukliďte data v počítači

Jak dobře koupit starší telefon

Vylepšete zvuk televize: test 7 soundbarů