Kezdőoldal » Számítástechnika » Programozás » Aki megérti ezt, már ha van...

Aki megérti ezt, már ha van aki megérti, eltudná magyarázni?

Figyelt kérdés

// TEMPLATE STRUCT SPECIALIZATION equal_to

template<>

struct equal_to<void>

{ // transparent functor for operator==

typedef _Is_trans is_transparent;


template<class _Ty1,

class _Ty2>

_CONST_FUN auto operator()(_Ty1&& _Left, _Ty2&& _Right) const

-> decltype(static_cast<_Ty1&&>(_Left)

== static_cast<_Ty2&&>(_Right))

{ // transparently apply operator== to operands

return (static_cast<_Ty1&&>(_Left)

== static_cast<_Ty2&&>(_Right));

}

};



2015. aug. 2. 06:44
 1/7 anonim ***** válasza:
100%

Hát nem látok mindent, mivel ez nem egy teljes példa. Pl. mi az eredeti template amit specializál, mi az _Is_trans és mi a _CONST_FUN makró? Elmagyarázom a ritkábban használt elemek jelentését, összerakhatod a képet belőle.


Ez egy osztály template specializáció, ami gondolom a void behelyettesítést adja meg egy korábbi template-hez.


A belső függvény pedig perfect forwarding-ot használ. A _Ty1 és _Ty2 template paraméter, ezért a _Ty1&& típusú és _Ty2&& típusú paraméterek forwarding reference-nek számítanak. Azaz képes bal- és jobbreferencia átvételére egyaránt és minden típusra.


A visszatérési érték típusa kikövetkeztetéssel történik (auto kulcsszó a visszetérési érték típusa helyén). A "-> decltype(...)" adja meg a típusát. Pl. a kifejezés bool értékű lehet, ekkor bool&&, bool& és bool lehet a visszatérési érték típusa. Kikerestem a szabályt:


"2) If the argument is any other expression of type T, then

a) if the value category of expression is xvalue, then the decltype specifies T&&

b) if the value category of expression is lvalue, then the decltype specifies T&

c) otherwise, decltype specifies T"


[link]

[link]


A static_cast meg egyszerűen egy cast, bizonyos megkötéssel. Feltételezem nem ez a gond.

2015. aug. 2. 10:27
Hasznos számodra ez a válasz?
 2/7 anonim ***** válasza:
100%

Elég érdekes kódrészlet, nem ártana látni a teljes programot, mert így megvágva nincs sok értelme. Azért végigrágom, hogy mit lehet tudni róla:


template<>

struct equal_to<void>


Ez eleve egy olyan template osztály specializál, amit nem látunk. Ráadásul void típust ad meg, amit értelmes programok ritkán szoktak használni. Inkább tűnik valami közepes minőségű tankönyvi példának.


typedef _Is_trans is_transparent;

Ezt ennyiből nem lehet megmondani, de _ jellel kezdeni osztályt nem valami jó névkonvenció.


template<class _Ty1,

class _Ty2>


Template függvény fog következni


_CONST_FUN


Nincs róla infónk, nagyon remélem, hogy nem a constexpr-re csinált saját makrót.


auto operator()(_Ty1&& _Left, _Ty2&& _Right)


A függvény visszatérési értékét csak később árulja el, a bementi típusok Ty1 és Ty2. A && gondoskodik arról, hogy a bemeneti típus tekintettel legyen a deklarációs típusra, Tehát pla. a const int&& itt is const int&& lesz (rvalue reference).


-> decltype(static_cast<_Ty1&&>(_Left)

== static_cast<_Ty2&&>(_Right))


A visszatérési értéket határozza meg a compiler, úgy, hogy kiszámolja a zárójeles kifejezés értékét. (Ugyanez a kifejezés van a függvény hasában).

Ez C++14-nél teljesen felesleges, (tekintve, hogy a függvény visszatérési értékét decltype-olja), elég lett volna a decltype(auto) az auto helyett, és akkor az egész nyilas dolog nem kell.


return (static_cast<_Ty1&&>(_Left)

== static_cast<_Ty2&&>(_Right))


A static cast felesleges, hisz eleve perfect forwardinggal, tökéletesen típus azonosan vette át a változókat. De ha nem így vette volna át, akkor is hülyeség, emrt önmagára castol. De legalább a futás közbeni teljesítményt nem rontja, csak a fordítás lesz hosszabb.


Így viszont marad egy X == Y szerű kifejezés, tehát a bohóckodás a visszatérési értékkel is felesleges, ez ugyanis csak bool lehet. (Az operator == visszatérési értékét rögzíti a szabvány).


Ezzel a sok maszlaggal le tudod írni azt, hogy


equal_to<void> comparator;

comparator(x,y);


Ami ugyanaz, mintha ennyit írtál volna:


x == y;


Minél többet nézem a kódot, annál inkább úgy gondolom, hogy vagy nem vettem észre valami nagyon alapvető dolgot, vagy ez egy terjengős hülyeség. Lehet, hogy a teljes kontextusban értelmet nyer. Honnan van?

2015. aug. 2. 15:15
Hasznos számodra ez a válasz?
 3/7 anonim ***** válasza:
Kicsit még gondolkoztam rajta, és lehet, hogy ez valami nagy template magic delegátor része, amire csak azért van szükség, hogy a többi, egyedi tempalte funkcionalitással azonos módon lehessen az operátor ==-t elérni. De nem tudnék ilyen varázslatot mondani. Viszont a C++ 14-ben a templatek már külön életet élnek, eszméletlen dolgokat csinálnak, így vigyázni kell azzal, mire mondjuk, hogy használhatatlan.
2015. aug. 2. 18:10
Hasznos számodra ez a válasz?
 4/7 A kérdező kommentje:

Valóban nem írtam le részletesen honnan van és mégis mire használatos, ezért elnézést (bár ha leírom honnan van nyilván tudjátok mire való).

A kódrészlet a 'xstddef' header fájlból van (STD névtér):

#define _CONST_FUN constexpr (VS 2013 még nem támogatta, így ott gondolom const volt helyette)


A kérdést azért tettem fel, mert szerettem volna megtudni hogyan működnek az ehhez hasonló funkciók és miért úgy ahogy:


std::vector<double> v = {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10};


double osszeg = 0;

osszeg = std::accumulate(v.cbegin(), v.cend(), osszeg, std::plus<>());


std::cout << osszeg << '\n';


A std::plus bonyolult változata úgy néz ki mint a kérdésemben írt példa, de ezek szerint ha magamnak írok hasonlót teljesen ugyan az a hatás így is:


template<class _Ty = void>

struct plus

{

constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const

{

return (_Left + _Right);

}

};


template<>

struct plus<void>

{

template<class _Ty1, class _Ty2>

constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const

{

return _Left + _Right;

}

};


Illetve a linkelteken kívül, 2 link ami még segített megérteni:

[link]

[link]


Köszönöm a válaszokat!

2015. aug. 2. 19:37
 5/7 anonim ***** válasza:
100%

>> A static cast felesleges, hisz eleve perfect forwardinggal, tökéletesen típus azonosan vette át a változókat. De ha nem így vette volna át, akkor is hülyeség, emrt önmagára castol. De legalább a futás közbeni teljesítményt nem rontja, csak a fordítás lesz hosszabb.


Nem hülyeség, mert nem megfelelő a paraméter átadás. Pont a belinkelt stack overflow-s kérdésben van részletesen leírva, hogy nem felesleges. Inkább forward<_Ty1>(_Left)-t kellene írni static_cast<_Ty1&&>(_Left) helyett.

2015. aug. 2. 20:25
Hasznos számodra ez a válasz?
 6/7 anonim ***** válasza:

Igen, a castot (forwardot) tényleg benéztem, az oda mindenképp kell.


Igazából kíváncsi vagyok, az std ezt mire használja. Felkeltetted az érdeklődésemet.

2015. aug. 2. 21:14
Hasznos számodra ez a válasz?
 7/7 A kérdező kommentje:

Akit bővebben érdekel itt van még 2 link:


[link]


[link]

2015. aug. 2. 21:49

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!