Sınıf içinde şablon işlevi nasıl oluşturulur? (C ++)


144

Bir şablon işlevi yapmanın mümkün olduğunu biliyorum:

template<typename T>
void DoSomeThing(T x){}

ve bir şablon sınıfı yapmak mümkündür:

template<typename T>
class Object
{
public:
    int x;
};

ancak şablonu şablon içinde olmayan bir sınıf haline getirmek ve sonra bu sınıftaki bir işlevi şablon yapmak mümkün müdür? yani:

//I have no idea if this is right, this is just how I think it would look
class Object
{
public:
    template<class T>
    void DoX(){}
};

ya da sınıfın bir şablonun parçası olmadığı, ancak işlev?

Yanıtlar:


115

Tahmininiz doğru. Hatırlamanız gereken tek şey, üye işlev şablonu tanımının (bildirime ek olarak) , sınıf bildiriminin kendisinde olması gerekmese de, başlık dosyasında, cpp'de olmaması gerektiğidir.


3
Ve ayrıca onları uzmanlaştıramazsınız. :-(
— Frank Krueger

7
Tam olarak doğru değil. Tanım, tanımlandıktan sonra şablon olmayan bir işlevden / yöntemden her bir benzersiz şablon parametresi n-upleti için bir kez çağrıldığı sürece, bir cpp dosyasında olabilir.
— Benoît

1
Bu yüzden benim “yapmam” - bunu başlıkta tutmak bunu başarmanın en basit yoludur.
— Emin değilim

4
Aslında, onları açıkça uzmanlaştırabileceğinize inanıyorum, ancak kısmen uzmanlaşamazsınız. Ne yazık ki bunun derleyiciye özel bir uzantı mı yoksa C ++ standardı mı olduğunu bilmiyorum.
— Patrick Johnmeyer

7
Aslında standart c ++. A {template <typename> void f () yapısını yapabilirsiniz; }; örneğin <> void A :: f <int> () {}. Bunları sınıf kapsamında uzmanlaştıramazsınız, ancak ad alanı kapsamında tamamladığınızda bunu iyi yapabilirsiniz. (uzmanlığın gerçekte konulduğu kapsamla karıştırılmamalıdır: uzmanlık hala sınıfın bir üyesi olacaktır - ancak tanımı isim alanı kapsamında yapılır. Genellikle bir şeyin konulduğu kapsam kapsamla aynıdır bir şey tanımlanır - ancak bu, sınıf dışı tanımların tüm vakalarında olduğu gibi bazen doğru değildir)
— Johannes Schaub - litb

70

Buraya bakın: Şablonlar , şablon yöntemleri , Üye Şablonları, Üye İşlev Şablonları

class   Vector
{
  int     array[3];

  template <class TVECTOR2> 
  void  eqAdd(TVECTOR2 v2);
};

template <class TVECTOR2>
void    Vector::eqAdd(TVECTOR2 a2)
{
  for (int i(0); i < 3; ++i) array[i] += a2[i];
}

iyi örnek. ama neden <typename T> şablonu sınıf definitino'nun içinde? ???
— Martian2049

@ Martian2049 Bunun şablonun bir bütün olarak sınıf için değil, sadece sınıf içindeki üye işlevi için geçerli olduğunu düşünüyorum. Tam olarak OP'nin istediği gibi.
— CBK

21

Evet, şablon üyesi işlevleri çok sayıda yasal ve yararlıdır.

Tek uyarı şablon üyesi işlevlerinin sanal olamayacağıdır.


9

En kolay yol, bildirimi ve tanımı aynı dosyaya koymaktır, ancak aşırı büyük boyutlu çıkarılabilir dosyaya neden olabilir. Örneğin

class Foo
{
public:
template <typename T> void some_method(T t) {//...}
}

Ayrıca, şablon tanımını ayrı dosyalara koymak, yani .cpp ve .h dosyalarına koymak mümkündür. Tek yapmanız gereken, şablon örneğini .cpp dosyalarına açıkça dahil etmektir. Örneğin

// .h file
class Foo
{
public:
template <typename T> void some_method(T t);
}

// .cpp file
//...
template <typename T> void Foo::some_method(T t) 
{//...}
//...

template void Foo::some_method<int>(int);
template void Foo::some_method<double>(double);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.