Barton–Nackman-trükk

programnyelvi minta

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

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

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

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

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

Jegyzetek

Fordítá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.