Invocation: problems with function template overload resolution
Why is our specialisation of `std::get` not picked up by the compiler? * it must somehow be related to the fact that `std::tuple` itself is a base class of lib::HeteroData * if we remove this inheritance relation, our specialisation is used by the compiler and works as intended * however, this strange behaviour can not be reproduced in a simple synthetic setup It must be some further subtlety which marks the tuple case as preferrable
This commit is contained in:
parent
f2f321a3b8
commit
4a7e1eeb36
4 changed files with 136 additions and 153 deletions
144
research/try.cpp
144
research/try.cpp
|
|
@ -1,18 +1,15 @@
|
|||
/* try.cpp - to try out and experiment with new features....
|
||||
* scons will create the binary bin/try
|
||||
*/
|
||||
// 12/24 - investigate overload resolution on a templated function similar to std::get
|
||||
// 11/24 - how to define a bare object location comparison predicate
|
||||
// 11/23 - prototype for grouping from iterator
|
||||
|
||||
|
||||
/** @file try.cpp
|
||||
* Attempt to generalise the util::isSameObject, to support a mix of pointers and references.
|
||||
* This is a long standing requirement, yet I made several failed attempts in the past,
|
||||
* due to difficulties detecting a pointer after perfect-forwarding the argument. However,
|
||||
* it is not even necessary to perfect-forward, if all we want is to extract the raw address.
|
||||
*
|
||||
* To my defence, I should add that I never took the time to conduct a proper experiment
|
||||
* in a stand-alone setup; investigating directly in "lib/util.hpp" is a waste of time.
|
||||
* Find out about the conditions when an overload of a function template is picked.
|
||||
* This is an investigation regarding the proper way to overload std::get
|
||||
* especially when the base class of the custom type itself is a tuple.
|
||||
*/
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
|
@ -25,109 +22,56 @@ typedef unsigned int uint;
|
|||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
using lib::rani;
|
||||
using std::move;
|
||||
using std::string;
|
||||
using lib::test::showType;
|
||||
|
||||
template<class X>
|
||||
inline const void*
|
||||
getAd (X& x)
|
||||
{
|
||||
return static_cast<const void*> (std::addressof(x));
|
||||
}
|
||||
template<class X>
|
||||
inline const void*
|
||||
getAd (X* x)
|
||||
{
|
||||
return static_cast<const void*> (x);
|
||||
}
|
||||
template<typename...TS>
|
||||
string
|
||||
showTypes()
|
||||
{
|
||||
return "<" + ((showType<TS>()+",") + ... + ">");
|
||||
}
|
||||
|
||||
template<class A, class B>
|
||||
inline bool
|
||||
isSameOb (A const& a, B const& b)
|
||||
{
|
||||
return getAd(a)
|
||||
== getAd(b);
|
||||
}
|
||||
|
||||
using std::tuple;
|
||||
|
||||
struct Boo
|
||||
{
|
||||
string moo;
|
||||
short goo;
|
||||
|
||||
Boo(short uh)
|
||||
: moo{util::toString(uh-1)}
|
||||
, goo(uh+1)
|
||||
{ }
|
||||
|
||||
operator string() const
|
||||
{
|
||||
return moo+util::toString(goo);
|
||||
}
|
||||
};
|
||||
|
||||
struct SuBoo : Boo
|
||||
{
|
||||
long poo = rani(goo);
|
||||
|
||||
using Boo::Boo;
|
||||
};
|
||||
struct B { };
|
||||
|
||||
|
||||
|
||||
inline Boo*
|
||||
asBoo (void* mem)
|
||||
{// type tag to mark memory address as Buffer
|
||||
return static_cast<Boo*> (mem);
|
||||
}
|
||||
|
||||
struct D1 : B { };
|
||||
|
||||
struct D2 : D1 { };
|
||||
|
||||
string getty (B&) { return "getty-B&"; }
|
||||
string getty (D1&&){ return "getty-D1&&"; }
|
||||
string getty (D1&) { return "getty-D1&"; }
|
||||
|
||||
|
||||
|
||||
template<class...TS>
|
||||
string getty (tuple<TS...>&) { return "getty-tuple& "+showTypes<TS...>(); }
|
||||
|
||||
|
||||
template<class...TS>
|
||||
struct F : tuple<TS...> { };
|
||||
|
||||
template<class...TS>
|
||||
struct FD1 : F<TS...> {};
|
||||
|
||||
template<class...TS>
|
||||
struct FD2 : FD1<TS...> {};
|
||||
|
||||
|
||||
template<class...TS>
|
||||
string getty (FD1<TS...>&) { return "getty-FD1& "+showTypes<TS...>(); }
|
||||
|
||||
int
|
||||
main (int, char**)
|
||||
{
|
||||
Boo boo(23);
|
||||
Boo booo(23);
|
||||
Boo* boop = &boo;
|
||||
Boo const* const beep = boop;
|
||||
cout << boo << endl;
|
||||
SHOW_EXPR(util::showAdr(getAd(boo )))
|
||||
SHOW_EXPR(util::showAdr(getAd(&boo)))
|
||||
SHOW_EXPR(util::showAdr(getAd(boop)))
|
||||
SHOW_EXPR(util::showAdr(getAd(beep)))
|
||||
SHOW_EXPR(isSameOb(boop, beep))
|
||||
SHOW_EXPR(isSameOb(&boop, &beep))
|
||||
SHOW_EXPR(isSameOb(boo, beep))
|
||||
SHOW_EXPR(isSameOb(*beep, booo))
|
||||
SHOW_EXPR(isSameOb(boo, boo.moo))
|
||||
SHOW_EXPR(isSameOb(boo, &boo.moo))
|
||||
SHOW_EXPR(isSameOb(boo.moo, booo))
|
||||
SHOW_EXPR(isSameOb(booo, asBoo(&booo.moo)))
|
||||
SHOW_EXPR(isSameOb(booo, asBoo(&booo.goo)))
|
||||
|
||||
const void* voo = boop;
|
||||
SHOW_EXPR(isSameOb(voo, boo))
|
||||
SHOW_EXPR(isSameOb(voo, boop))
|
||||
SHOW_EXPR(isSameOb(voo, asBoo(&boo.moo)))
|
||||
SHOW_EXPR(isSameOb(voo, asBoo(&booo.moo)))
|
||||
SHOW_EXPR(isSameOb(voo, asBoo(&boo.goo)))
|
||||
D2 d2;
|
||||
SHOW_EXPR(getty(d2));
|
||||
|
||||
Boo&& roo = move(boo);
|
||||
SHOW_EXPR(isSameOb(roo, boo))
|
||||
SHOW_EXPR(isSameOb(voo, roo))
|
||||
SHOW_EXPR(isSameOb(voo, Boo{roo}))
|
||||
|
||||
SuBoo* suBoo = static_cast<SuBoo*>(&boo);
|
||||
SHOW_EXPR(isSameOb(boo, suBoo))
|
||||
SHOW_EXPR(isSameOb(boo, suBoo->moo))
|
||||
SHOW_EXPR(isSameOb(voo, suBoo->moo))
|
||||
SHOW_EXPR(isSameOb(voo, suBoo->poo))
|
||||
|
||||
SuBoo sudo{*suBoo};
|
||||
SHOW_EXPR(isSameOb(sudo, suBoo))
|
||||
suBoo = &sudo;
|
||||
SHOW_EXPR(isSameOb(sudo.poo, suBoo->poo))
|
||||
FD2<int, char**> fd2;
|
||||
SHOW_EXPR(getty(fd2));
|
||||
|
||||
cout << "\n.gulp.\n";
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace lib {
|
|||
|
||||
template<size_t seg, typename...DATA>
|
||||
struct StorageFrame
|
||||
: protected StorageLoc
|
||||
: StorageLoc
|
||||
, std::tuple<DATA...>
|
||||
{
|
||||
using Tuple = std::tuple<DATA...>;
|
||||
|
|
@ -88,13 +88,16 @@ namespace lib {
|
|||
|
||||
template<size_t seg, typename...DATA, class TAIL>
|
||||
class HeteroData<meta::Node<StorageFrame<seg, DATA...>,TAIL>>
|
||||
: StorageFrame<seg, DATA...>
|
||||
// : StorageFrame<seg, DATA...>
|
||||
// : util::NonCopyable
|
||||
{
|
||||
using _Self = HeteroData;
|
||||
using _Tail = HeteroData<TAIL>;
|
||||
using Tuple = std::tuple<DATA...>;
|
||||
using Frame = StorageFrame<seg, DATA...>;
|
||||
|
||||
Frame frame_;
|
||||
|
||||
static constexpr size_t localSiz = sizeof...(DATA);
|
||||
|
||||
template<size_t slot>
|
||||
|
|
@ -107,14 +110,17 @@ namespace lib {
|
|||
_Tail&
|
||||
accessTail()
|
||||
{
|
||||
REQUIRE (Frame::next, "HeteroData storage logic broken: follow-up extent not yet allocated");
|
||||
return * reinterpret_cast<_Tail*> (Frame::next);
|
||||
REQUIRE (frame_.next, "HeteroData storage logic broken: follow-up extent not yet allocated");
|
||||
return * reinterpret_cast<_Tail*> (frame_.next);
|
||||
}
|
||||
|
||||
template<typename...XX>
|
||||
friend class HeteroData; ///< allow chained types to use recursive type definitions
|
||||
|
||||
using Frame::Frame;
|
||||
template<typename...INIT>
|
||||
HeteroData (INIT&& ...initArgs)
|
||||
: frame_{std::forward<INIT> (initArgs)...}
|
||||
{ }
|
||||
|
||||
public:
|
||||
HeteroData() = default;
|
||||
|
|
@ -135,7 +141,7 @@ namespace lib {
|
|||
{
|
||||
static_assert (slot < size(), "HeteroData access index beyond defined data");
|
||||
if constexpr (slot < localSiz)
|
||||
return std::get<slot> (*this);
|
||||
return std::get<slot> (frame_);
|
||||
else
|
||||
return accessTail().template get<slot-localSiz>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,8 +131,8 @@ namespace test{
|
|||
CHECK ((showType<std::tuple_element_t<1, Block2>>() == "string"_expect));
|
||||
|
||||
CHECK (std::get<0> (chain2) == 42);
|
||||
// CHECK (std::get<1> (chain2) == "1.618034"_expect); ////////////////////////////TODO somehow the overload for std::tuple takes precedence here
|
||||
// CHECK (std::get<2> (chain2) == "Φ"_expect);
|
||||
CHECK (std::get<1> (chain2) == "1.618034"_expect); ////////////////////////////TODO somehow the overload for std::tuple takes precedence here
|
||||
CHECK (std::get<2> (chain2) == "Φ"_expect);
|
||||
|
||||
CHECK (std::get<0> (b2) == "1.618034"_expect);
|
||||
CHECK (std::get<1> (b2) == "Φ"_expect);
|
||||
|
|
|
|||
|
|
@ -22649,9 +22649,7 @@
|
|||
<node CREATED="1540639934819" ID="ID_1733133201" MODIFIED="1557498707225" TEXT="...da es sich um ein Attribut-Binding handelt"/>
|
||||
<node CREATED="1540639945978" ID="ID_1136500098" MODIFIED="1576282358082" TEXT="(sollte aber auch niemals auftreten)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...da wir unterstellen, daß das Gegenstück im Session-Modell,
|
||||
|
|
@ -22986,9 +22984,7 @@
|
|||
<node CREATED="1480780253397" ID="ID_1966427410" MODIFIED="1518487921082" TEXT="zum Preis von deutlich Mehraufwand"/>
|
||||
<node CREATED="1480780260508" ID="ID_1565963038" MODIFIED="1539382659215" TEXT="plus einer korrodierenden Wirkung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...welche darin besteht,
|
||||
|
|
@ -23396,9 +23392,7 @@
|
|||
</node>
|
||||
<node CREATED="1666476675737" ID="ID_489715422" MODIFIED="1678406261536">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<u>Dienst</u>: aktueller Skalenfaktor + Offset
|
||||
|
|
@ -24200,9 +24194,7 @@
|
|||
</node>
|
||||
<node CREATED="1582992315675" ID="ID_1937379462" MODIFIED="1582992414632">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Auslösen durch <b><font color="#7a264c">signalStructureChange</font></b>
|
||||
|
|
@ -25342,9 +25334,7 @@
|
|||
<node CREATED="1674603535772" ID="ID_1899820582" MODIFIED="1674603556532" TEXT="manchmal erfolgt dann kein Update / re-Draw beim Dragging"/>
|
||||
<node CREATED="1674603557497" ID="ID_1941260000" MODIFIED="1674603679778" TEXT="die Position wird aber korrekt berechnet und gesetzt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
nachweislich...
|
||||
|
|
@ -27410,9 +27400,7 @@
|
|||
<node CREATED="1677365093931" ID="ID_1368458373" MODIFIED="1677365099512" TEXT="Bogen">
|
||||
<node CREATED="1677368264383" ID="ID_1877634925" MODIFIED="1677368499104" TEXT="jeweils in Radians">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
↶ freeCAD : rechtsdrehend(mathematisch)
|
||||
|
|
@ -30944,9 +30932,7 @@
|
|||
<node CREATED="1555020163776" ID="ID_1470546162" MODIFIED="1557498707229" TEXT="collapsed == Scope durch Ruler ersetzt"/>
|
||||
<node CREATED="1555020175102" ID="ID_1798602" MODIFIED="1557498707229">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<i>das </i>ist ein reiner (pesistent) presentation state
|
||||
|
|
@ -31769,9 +31755,7 @@
|
|||
</node>
|
||||
<node CREATED="1563033292565" ID="ID_1632267547" MODIFIED="1563033473194" TEXT="aktuell ist der Pfad schon sinnvoll (aber noch nicht ideal)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
window:backdrop:dir-ltr.background box:backdrop:dir-ltr.vertical box:backdrop:dir-ltr[2/3].horizontal widget:backdrop:dir-ltr[2/2] widget:backdrop:dir-ltr paned:backdrop:dir-ltr.vertical widget:backdrop:dir-ltr box:backdrop:dir-ltr.vertical notebook:backdrop:dir-ltr[1/1].frame paned:backdrop:dir-ltr.horizontal box:backdrop:dir-ltr.vertical fork.timeline
|
||||
|
|
@ -35471,9 +35455,7 @@
|
|||
<node CREATED="1666474895435" ID="ID_1743952496" MODIFIED="1666474895435" TEXT="per Zeit an den Canvas geheftet"/>
|
||||
<node CREATED="1612473206764" ID="ID_383710389" MODIFIED="1666475206066" TEXT="Widget kann sich selbst um seine eigene Ausdehnung kümmern">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das mag überraschend sein — erst dachte ich, es sein ein Nachteil, aber tatsächlich fügt es sich natürlich in die Layout-Steuerung von GTK ein; denn GTK fragt ja das Widget nach seiner benötigten Ausdehnung, und das ist auch genau der Mechanismus, über den wir eine Beschränkung auf eine vorgegebene zeitliche Ausdehnung realisieren. Zudem hat das Widget die Information über seine eigene Ausdehnung als Zeitangabe vorliegen, und das paßt dann auch gut in dieses Aufrufschema
|
||||
|
|
@ -37735,9 +37717,7 @@
|
|||
<node CREATED="1616709888782" ID="ID_1557466321" MODIFIED="1616709896625" TEXT="mit einer Interaktionsform"/>
|
||||
<node CREATED="1616709937487" ID="ID_1221710731" MODIFIED="1616709984652" TEXT="idealerweise abstrakt und übergreifend">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das Ideal wäre, daß man das nicht speziell für Maus, Tastatur, Stift und Hardware einrichten muß, sondern lediglich qualifizieren
|
||||
|
|
@ -38967,9 +38947,7 @@
|
|||
</node>
|
||||
<node CREATED="1620406074960" ID="ID_1455403417" MODIFIED="1620406114628">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
wenn wir trotzdem einen Overrun-Check haben wollen,
|
||||
|
|
@ -39378,9 +39356,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1616684916746" ID="ID_571239713" MODIFIED="1616684947088">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
2.Schritt: <i>rektifizieren</i>
|
||||
|
|
@ -39647,9 +39623,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1672672729523" ID="ID_204825395" MODIFIED="1672672853253" TEXT="vorerst durch generische Regel im Code festgelegt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...später möchte ich diesen als eigenen zusätzlichen Freiheitsgrad einführen; dazu muß aber bereits mehr über den Verwendungszusammenhang bekannt sein; insofern habe ich vorerst eine generische Regel implementiert, die den Zoom-Anchor anhand der Position zum Gesamt-Canvas festlegt (ganz am Anfgang liegt er ganz links, am Ende ganz rechts)
|
||||
|
|
@ -40050,9 +40024,7 @@
|
|||
</node>
|
||||
<node CREATED="1668176234367" ID="ID_762072729" MODIFIED="1668176354941" TEXT="...sondern an allen potentiell gefährlichen Rechenschritten explizit auf Wert-Erhalt abgestellt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das heißt...
|
||||
|
|
@ -88268,8 +88240,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
sollte <i>im Prinzip ja</i> einfach sein...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#3362d9" DESTINATION="ID_609631801" ENDARROW="Default" ENDINCLINATION="-1197;56;" ID="Arrow_ID_145396423" STARTARROW="None" STARTINCLINATION="-581;47;"/>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1733946491575" ID="ID_1678748014" MODIFIED="1733946694559" TEXT="tuple_len">
|
||||
|
|
@ -88296,6 +88268,57 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1733946765784" ID="ID_1087783493" MODIFIED="1733946780713" TEXT="das bekannte Problem mit Funktion Overloads"/>
|
||||
<node CREATED="1733946781559" ID="ID_1787763968" MODIFIED="1733946793699" TEXT="es ist dann eben keine partielle Template-Spezialisierung"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1733960761558" ID="ID_1977939692" MODIFIED="1733960781184" TEXT="trotzdem verstehe ich das Problem nicht.....">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1733960786954" ID="ID_1320100813" MODIFIED="1733960810467" TEXT="er sollte dann doch den gegebenen Overload verwenden"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1733960871534" ID="ID_1458313610" MODIFIED="1733960901968" TEXT="versuche mal den std::tuple-Basistyp herauszunehmen">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1733964059183" ID="ID_39714121" MODIFIED="1733964345755" TEXT="vorsicht Empty-Baseclass">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
HeteroData darf dann <i>gar keine Basisklasse haben.</i> Denn die empty-baseclass-optimisation ist optional; letztlich läßt der Standard dem konkreten Compiler einigen Spielraum bezüglich des Speicher-Layouts
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1733964072098" ID="ID_374917909" MODIFIED="1733964090307" TEXT="Frame muß als erstes Member in HeteroData liegen"/>
|
||||
<node CREATED="1733964092091" ID="ID_715175218" MODIFIED="1733964257280" TEXT="natürlich wäre diese Lösung bedeutent unklarer">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Die Definition mit dem Frame als Basisklasse erscheint mir sauberer, denn sie legt zweifelsfrei fest, wo der Frame sein soll und daß er mit dem Anfang von HeteroData zusammenfallen soll. Außerdem dokumentiert das eine is-a Beziehung (wenngleich auch die Sichtbarkeit eingeschränkt ist).
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1733964348236" ID="ID_1028912337" MODIFIED="1733970622428" TEXT="damit funktioniert der Test ⟹ meine Spezialisierung als Solche war korrekt"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1733964371585" ID="ID_440070050" MODIFIED="1733964386475" TEXT="warum wird dann trotzdem der Tuple-Overload gewählt?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1733970706145" ID="ID_1987504943" MODIFIED="1733970763130" TEXT="Overload-Resolution">
|
||||
<node CREATED="1733970768481" ID="ID_1455689693" MODIFIED="1733970773841" TEXT="drei Phasen">
|
||||
<node CREATED="1733970775984" ID="ID_1426251192" MODIFIED="1733970781923" TEXT="Phase-1 : Namen sammeln"/>
|
||||
<node CREATED="1733970783492" ID="ID_1265095943" MODIFIED="1733970791970" TEXT="Phase-2 : Kandidaten ausscheiden"/>
|
||||
<node CREATED="1733970793182" ID="ID_1827220461" MODIFIED="1733970804439" TEXT="Phase-3 : Rangordnung der verbleibenden Kandidaten"/>
|
||||
</node>
|
||||
<node CREATED="1733970712987" ID="ID_1572539784" LINK="https://en.cppreference.com/w/cpp/language/overload_resolution" MODIFIED="1733970751100" TEXT="Basis-Regeln"/>
|
||||
<node CREATED="1733970720145" ID="ID_1764534136" LINK="https://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading" MODIFIED="1733970760198" TEXT="Regeln für Funktions-Templates"/>
|
||||
</node>
|
||||
<node CREATED="1733970625236" ID="ID_1475799809" MODIFIED="1733970641577" TEXT="beide Kandidaten sind Funktions-Templates"/>
|
||||
<node CREATED="1733970647177" ID="ID_305236337" MODIFIED="1733970684664" TEXT="Parameter ⟼ Tuple(Base) gilt als Conversion"/>
|
||||
<node CREATED="1733970685828" ID="ID_442077561" MODIFIED="1733970703973" TEXT="deshalb sollte m.E. dieser Fall einen schlechteren Rang bekommen"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1733970909696" ID="ID_1168280520" MODIFIED="1733970922306" TEXT="Untersuchung">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1733972793050" ID="ID_1370589924" MODIFIED="1733972813148" TEXT="im einfachen Beispiel verhält sich alles wie erwartet...">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -142743,7 +142766,17 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1715693174737" ID="ID_152113212" MODIFIED="1715725332461" TEXT="(custom)Allocator">
|
||||
<node CREATED="1733950360795" ID="ID_28461925" MODIFIED="1733950367973" TEXT="Tupel und structured binding">
|
||||
<node CREATED="1733950416539" ID="ID_1732623981" MODIFIED="1733950431054" TEXT="man kann damit ein Tupel in lokale Variable auspacken">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1733950377664" ID="ID_242038986" LINK="https://en.cppreference.com/w/cpp/utility/tuple/tuple-like" MODIFIED="1733950483299" TEXT="verwendbar für alles was das »tuple protocoll« erfüllt"/>
|
||||
<node COLOR="#435e98" CREATED="1733950233731" ID="ID_609631801" LINK="https://devblogs.microsoft.com/oldnewthing/20201015-00/?p=104369" MODIFIED="1733950498051" TEXT="How to add structured binding support to your own types">
|
||||
<linktarget COLOR="#3362d9" DESTINATION="ID_609631801" ENDARROW="Default" ENDINCLINATION="-1197;56;" ID="Arrow_ID_145396423" SOURCE="ID_1814813251" STARTARROW="None" STARTINCLINATION="-581;47;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1715693174737" FOLDED="true" ID="ID_152113212" MODIFIED="1715725332461" TEXT="(custom)Allocator">
|
||||
<linktarget COLOR="#4961d5" DESTINATION="ID_152113212" ENDARROW="Default" ENDINCLINATION="-2030;323;" ID="Arrow_ID_717223261" SOURCE="ID_868305899" STARTARROW="None" STARTINCLINATION="-1527;135;"/>
|
||||
<node CREATED="1715693298760" ID="ID_1472333314" MODIFIED="1715693300284" TEXT="Quellen">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1715696253175" ID="ID_267534641" MODIFIED="1715696324289" TEXT="CPP-Referenz">
|
||||
|
|
|
|||
Loading…
Reference in a new issue