diff --git a/src/lib/text-template.hpp b/src/lib/text-template.hpp index 4a16bee04..b101debcd 100644 --- a/src/lib/text-template.hpp +++ b/src/lib/text-template.hpp @@ -317,8 +317,6 @@ namespace lib { bool loopFurther(); }; - template - using InstanceIter = ExploreIter>>; ActionSeq actions_; @@ -328,7 +326,7 @@ namespace lib { { } template - InstanceIter + auto submit (DAT const& data) const; template @@ -536,6 +534,8 @@ namespace lib { static_assert (not sizeof(DAT), "unable to bind this data source " "for TextTemplate instantiation"); + + DataSource (DAT const&); }; using MapS = std::map; @@ -561,7 +561,7 @@ namespace lib { template<> struct TextTemplate::DataSource { - MapS const * data_; + MapS const * data_{nullptr}; string keyPrefix_{}; bool isNested() { return not isnil (keyPrefix_); } @@ -642,6 +642,29 @@ namespace lib { } }; + namespace {// help the compiler with picking the proper specialisation for the data binding + + template> > + inline auto + bindDataSource(STR const& spec) + { + return TextTemplate::DataSource{spec}; + } + + inline auto + bindDataSource(MapS const& map) + { + return TextTemplate::DataSource{map}; + } + + /* Why this approach? couldn't we use CTAD? + * - for one, there are various compiler bugs related to nested templates and CTAD + * - moreover I am unable to figure out how to write a deduction guide for an + * user provided specialisation, given possibly within another header. + */ + } + + /* ======= implementation of the instantiation state ======= */ @@ -821,10 +844,10 @@ namespace lib { * thereby producing a sequence of `std::string_view&` */ template - inline TextTemplate::InstanceIter + inline auto TextTemplate::submit (DAT const& data) const { - return explore (InstanceCore{actions_, DataSource{data}}); + return explore (InstanceCore{actions_, bindDataSource(data)}); } /** submit data and materialise rendered results into a single string */ diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 0ead2d102..8219d67db 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -79558,7 +79558,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -113501,14 +113501,93 @@ std::cout << tmpl.render({"what", "World"}) << s - + - + + + + + + + +

+ zunächst einmal: Deklaration kann auto verwenden +

+ + +
+
+ + + + + + + + + + + + +

+ Grund: die expliziten Spezialisierungen kommen überhaupt erst ins's Spiel, wenn der Compiler die konkreten Template-Argumente bereits erschlossen hat. Vorher schaut er nur in das primäre Template... und wenn das keinen Konstruktor hat, dann kennt der Compiler nur den Copy-Konstruktor. Die resultierende Fehlermeldung ist dann unglaublich hilfreich... +

+ + +
+ + +
+
+ + + + + + + + + + + + + + + +

+ Das sind die Limitierungen bei Function-Overloads. Mit Template-Deduction-Guides hätten wir dieses Problem vermutlich nicht (wenn wir sie denn schreiben könnten). +

+

+ +

+

+ Im Detail: Bei der Function Overload-Resolution werden die verschiedenen Kandidaten geordnet. Dabei werden zunächst alle überschüssigen und Default-Argumente weggestrichen. Konsequenz: ein enable-If kann zwar einen einzelnen Overload entfernen — wenn er aber nicht entfernt wurde, stehen zwei äquivalente Overloads da, und es gibt einen Compilation-Fehler. Rückgabewerte helfen hier auch nichts (die tragen nur zur const-ness-Auswahl bei). Das heißt, bei Function-Overload-Resolution muß das enable-If auf einem weiteren  Parameter stehen, der auch tatsächlich verwendet wird. Und an der Stelle wird's dann wirklich so trickreich, das es mir fragil erscheint. +

+ + +
+ +
+ + + + + + + + + + +
+
+
+ +
@@ -120849,7 +120928,8 @@ std::cout << tmpl.render({"what", "World"}) << s
- + + @@ -121044,6 +121124,80 @@ std::cout << tmpl.render({"what", "World"}) << s + + + + + + + + + + + + + +
+ explicit-specifier(optional) template-name (  parameter-decl-clause ) -> simple-template-id  ; + + +
+ +
+
+ + + + + + + + + + + + + + +

+ Automatic Deduction setzt ctor im primären  Template vorraus +

+ +
+ + + + + + + + +

+ ⟹ dann findet der Compiler ohne Hilfe keinen Construktor +

+ +
+ + + + + +

+ bzw. er findet nur den Copy-Konstruktur +

+ +
+ +
+
+
+ + + + + + + @@ -122442,7 +122596,9 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo - + + + @@ -123194,7 +123350,7 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo - +