Barton–Nackman-trükk
A Barton–Nackman-trükk egy John Barton és Lee Nackman által bevezetett programnyelvi minta. Szerzői korlátozott sablonkiterjesztésnek nevezték, a Barton–Nackman-trükk nevet a C++ szabványbizottság adta.[1]
Leírása
[szerkesztés]A mintát egy, az osztályban definiált barátfüggvény-definíció jellemzi, ami a Curiously Recurring Template Pattern bázisosztály sablonkomponensében jelenik meg.
// A class template to express an equality comparison interface.
template<typename T> class equal_comparable {
friend bool operator==(T const &a, T const &b) { return a.equal_to(b); }
friend bool operator!=(T const &a, T const &b) { return !a.equal_to(b); }
};
// Class value_type wants to have == and !=, so it derives from
// equal_comparable with itself as argument (which is the CRTP).
class value_type : private equal_comparable<value_type> {
public:
bool equal_to(value_type const& rhs) const; // to be defined
};
Ha egy osztálysablont mint az equal_comparable példányosítanak, az osztályban levő barátfüggvények nem sablon- és nem tagfüggvényeket hoznak létre, például operátorokat.
Használati eset
[szerkesztés]Bevezetésekor (1994) a C++ még nem definiált részben rendezést a túlterhelt függvénysablonokra, emiatt gyakran kérdéses volt a megfelelő függvény kiválasztása. Például az == generikus definíciója
template<typename T>
bool operator==(T const &a, T const &b) {
/* ... */
}
ütközött bármely másik definícióval, például
template<typename T>
bool operator==(Array<T> const &a, Array<T> const &b) {
/* ... */
}
A Barton–Nackman-trükk eléri, hogy a felhasználó által definiált generikus egyenlőségoperátor ne ütközzön. Az eredeti névben szereplő korlátozott szó arra utal, hogy az osztálybeli definíció csak az adott sablonosztály specializációra vonatkoztatható.
Az elnevezést gyakran hibásan használják a Curiously Recurring Template Patternre. Ez azonban egy másik kifejezés, amit a CRTP-hez lehet használni.
Működése
[szerkesztés]Ha a fordító ezt a kifejezést látja:
v1 == v2
ahol v1 és v2 érték típusú, argumentumfüggő keresést végez az == operátorra. Ez figyelembe veszi a megfelelő típus és őseinek barát függvényeit is. Ha ez egy még nem teljesen példányosult sablon, akkor ez kikényszeríti a teljes példányosítást.
A trükk eredetileg nem erre az argumentumfüggő keresésre vonatkozott, hanem a barát név injekció C++ feathurre, ahol az osztályban definiált barát függvény neve a teljes névtérben, akár a globális névtérben láthatóvá tette a függvény nevét. Ennek a megelőzésére ez a módszer bizonyult az egyetlen hatékony megoldásnak. Sőt, az argumentumfüggő keresést éppen a barát név injekció helyett javasolták,[2] ami fenntartotta a minta érvényességét. A változás eredményeképpen a
::operator==(v1,v2)
kifejezés már nem érvényes, ugyanis a minősített nevekre már nem vonatkozik az argumentumfüggő keresés. Ebből következően a friend minősítés lényegessé válik, még akkor is, ha a függvénynek nincs szüksége arra, hogy az osztály nem publikus elemeihez hozzáférjen.
Alternatív módszerek
[szerkesztés]A C++14 fogalmak (concept) alternatívát jelentenek a Barton–Nackman-trükk alkalmazásával szemben. A fogalmak generikus függvény specifikációk.
Források
[szerkesztés]- Vandevoorde, David. C++ Templates: The Complete Guide. Addison-Wesley Professional (2002). ISBN 0-201-73484-2
Jegyzetek
[szerkesztés]- ↑ Barton, John J.. Scientific and Engineering C++: An Introduction with Advanced Techniques and Examples. Addison-Wesley Professional (1994). ISBN 0-201-53393-6
- ↑ An Alternative to Name Injection from Templates (PDF). An Alternative to Name Injection from Templates. (Hozzáférés: 2005. április 12.)
Fordítás
[szerkesztés]Ez a szócikk részben vagy egészben a Barton–Nackman trick című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.