C++ Template Constructor

Ik wens een niet-sjabloonklasse te hebben met een sjabloonconstructeur zonder argumenten.

Voor zover ik begrijp, is het onmogelijk om het te hebben (omdat het in strijd zou zijn met de standaardconstructeur – AM I toch? ), en de workaround is het volgende:

class A{
   template <typename U> A(U* dummy) {
   // Do something
   }
};

Misschien is er een beter alternatief voor deze (of een betere oplossing)?


Antwoord 1, Autoriteit 100%

Er is geen manier om de sjabloonargumenten expliciet op te geven bij het bellen van een constructorjabloon, dus ze moeten worden afgeleid door middel van argumentaftrek. Dit komt omdat als je zegt:

Foo<int> f = Foo<int>();

De <int>is de Sjabloon-argumentlijst voor het type Foo, niet voor de constructor. Er is nergens voor de argumentlijst van de constructor sjabloon om te gaan.

Zelfs met uw oplossing moet u nog steeds een argument doorgeven om die constructorjabloon te bellen. Het is helemaal niet duidelijk wat u probeert te bereiken.


Antwoord 2, Autoriteit 34%

U kunt een gesignaleerde fabrieksfunctie maken:

class Foo
{
public:
    template <class T> static Foo* create() // could also return by value, or a smart pointer
    {
        return new Foo(...);
    }
...        
};

Antwoord 3, Autoriteit 24%

Voor zover ik begrijp, is het onmogelijk om het te hebben (omdat het in strijd zou zijn met de standaardconstructeur – ben ik toch?)

U bent verkeerd. Het is op geen enkele manier in conflict. Je kunt het gewoon niet bellen.


Antwoord 4, Autoriteit 21%

template<class...>struct types{using type=types;};
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;

De bovenstaande helpers laten u met typen als waarden werken.

class A {
  template<class T>
  A( tag<T> );
};

De tag<T>Type is een variabele zonder toestand naast het type IT-cariës. U kunt dit gebruiken om een ​​pure-typewaarde door te geven in een sjabloonfunctie en laat het type worden afgeleid door de sjabloonfunctie:

auto a = A(tag<int>{});

U kunt meer dan één type doorgeven:

class A {
  template<class T, class U, class V>
  A( types<T,U,V> );
};
auto a = A(types<int,double,std::string>{});

Antwoord 5, Autoriteit 16%

Enkele punten:

  • Als u Any declareert
    constructor (inclusief een gesorteerde
    één), de compiler zal afzien van
    een standaardconstructeur verklaren.
  • Tenzij u een kopie-constructeur verklaart (voor klasse X
    Dat neemt Xof X&of X const
    &
    ) De compiler genereert de
    Standaard kopie-constructeur.
  • Als u een sjabloonconstructeur voor Klasse X geeft die neemt
    T const &of Tof T&Dan de
    Compiler genereert toch een
    Standaard niet-sjabloon
    copy-constructor, ook al denk je misschien dat het niet zou moeten, want wanneer T = X de declaratie overeenkomt met de copy-constructor-declaratie.
  • In het laatste geval wil je misschien een niet-gemodelleerde kopie-constructor samen met de getemperde kopie verstrekken. Ze zullen niet conflicteren. Wanneer X wordt gepasseerd, wordt de niet-template aangeroepen. Anders de sjabloon

HTH


Antwoord 6, autoriteit 2%

Je zou dit kunnen doen:

class C 
{
public:
    template <typename T> C(T*);
};
template <typename T> T* UseType() 
{
    static_cast<T*>(nullptr);
}

Om vervolgens een object van het type Cte maken met behulp van intals de sjabloonparameter voor de constructor:

C obj(UseType<int>());

Omdat u sjabloonparameters niet aan een constructor kunt doorgeven, converteert deze oplossing in wezen de sjabloonparameter naar een reguliere parameter. Het gebruik van de functie UseType<T>()bij het aanroepen van de constructor maakt het voor iemand die naar de code kijkt duidelijk dat het doel van die parameter is om de constructor te vertellen welk type hij moet gebruiken.

Een gebruiksvoorbeeld hiervoor zou zijn als de constructor een afgeleid klasseobject maakt en dit toewijst aan een lidvariabele die een basisklasse-aanwijzer is. (De constructor moet weten welke afgeleide klasse hij moet gebruiken, maar de klasse zelf hoeft niet te worden getemperd omdat altijd hetzelfde pointertype van de basisklasse wordt gebruikt.)


Antwoord 7

Hier is een oplossing.

Maak een sjabloonsubklasse B van A. Voer het sjabloonargumentonafhankelijke deel van de constructie uit in de constructor van A. Doe het sjabloon-argumentafhankelijke deel in de constructor van B.


Antwoord 8

probeer iets te doen als

template<class T, int i> class A{
    A(){
          A(this)
    }
    A( A<int, 1>* a){
          //do something
    }
    A( A<float, 1>* a){
         //do something
    }
.
.
.
};

Antwoord 9

Gewoon eenvoudig een dummyvariabele toevoegen, zoals

class A {
  template<typename T>
  A(const T&, int arg1, int arg2);
}

Other episodes