Ugrás a tartalomhoz

Barton–Nackman-trükk

Ellenőrzött
A Wikipédiából, a szabad enciklopédiából

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]

Jegyzetek

[szerkesztés]
  1. Barton, John J.. Scientific and Engineering C++: An Introduction with Advanced Techniques and Examples. Addison-Wesley Professional (1994). ISBN 0-201-53393-6 
  2. 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.