Ansicht umschalten
Avatar von pre alpha
  • pre alpha

mehr als 1000 Beiträge seit 13.05.2006

constexpr + auto

Das crtp-Beispiel funktioniert auch mit unterschiedlichen Rückgabetypen und constexpr. Hätte sein können daß static_cast in interface() dazwischengrätscht, aber das ist nicht der Fall.
Mit concepts gehts ja sowieso, da kann man bei Bedarf/sinnvoll einschränken (auskommentiert).

namespace pre_alpha { template <typename Message> constexpr decltype(auto) decode(const Message& msg, const uint8_t key) noexcept { using type = std::array<char, Message{}.size()>; type res; for (size_t i=0; i<res.size(); ++i) { const char x = char(key + i); res[i] = char(msg[i] ^ x); } return res; } template <auto Message, uint8_t Key> struct message : std::integral_constant<decltype(decode(Message, Key)), decode(Message, Key)>{}; namespace crtp { template <typename Derived> struct Base { constexpr decltype(auto) interface() const noexcept { return static_cast<const Derived*>(this)->implementation(); } constexpr decltype(auto) implementation() const noexcept { return message<std::to_array<int>({71,109,109,115,117,60,107,113,109,0,69,71,77,4,108,97,111,40}), 23>::value.cbegin(); } }; struct Derived1 : Base<Derived1> { constexpr int implementation() const noexcept { return 42; } }; struct Derived2 : Base<Derived2> { constexpr double implementation() const noexcept { return 3.1415926; } }; struct Derived3 : Base<Derived3>{}; template <typename Type> constexpr decltype(auto) getMessage(const Type& base) noexcept { return base.interface(); } } // crtp namespace ente { struct MessageSeverity { constexpr decltype(auto) getMessage() const noexcept { return message<std::to_array<int>({122,94,88,68,64,15,29,17,86,90,81,21,115,89,76,78,83,88,87,81,75,81,39,97,52,44,41,101,21,36,32,60,38,35,35,43,61,44,56,61,145,247,51,48,36,119,34,44,55,123,23,47,55,58,7,18,20,6,22,7,20,2,11,1,15,25,64,77,3,6,4,81,22,22,25,85,35,26,15,28,29,91,191,193,28,26,242,161,230,230,234,165,205,235,237,249,254,228,231,255,239,251,245,255,146}), 42>::value.cbegin(); } }; struct MessageInformation { constexpr int getMessage() const noexcept { return 42; } }; struct MessageWarning { constexpr double getMessage() const noexcept { return 3.1415926; } }; struct MessageFatal : MessageSeverity{}; template <typename Type> concept MessageServer = requires(Type t) { t.getMessage(); //std::is_same_v<int, decltype(t.getMessage())>; }; template <MessageServer Type> constexpr decltype(auto) getMessage(const Type& messServer) noexcept { return messServer.getMessage(); } } // ente } // pre_alpha int main() { using namespace pre_alpha; crtp::Derived1 d1; constexpr auto d1r = crtp::getMessage(d1); std::cout << d1r << std::endl; crtp::Derived2 d2; constexpr auto d2r = crtp::getMessage(d2); std::cout << d2r << std::endl; crtp::Derived3 d3; constexpr auto d3r = crtp::getMessage(d3); std::cout << d3r << std::endl; std::cout << std::endl; ente::MessageInformation mi; constexpr auto mir = ente::getMessage(mi); std::cout << mir << std::endl; ente::MessageWarning mw; constexpr auto mwr = ente::getMessage(mw); std::cout << mwr << std::endl; ente::MessageFatal mf; constexpr auto mfr = ente::getMessage(mf); std::cout << mfr << std::endl; return EXIT_SUCCESS; }
Bewerten
- +
Ansicht umschalten