Bagaimana cara membuat fungsi templat di dalam kelas? (C ++)

144

Saya tahu mungkin membuat fungsi templat:

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

dan dimungkinkan untuk membuat kelas templat:

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

tetapi apakah mungkin untuk membuat kelas tidak di dalam template, dan kemudian membuat fungsi di kelas itu sebagai template? Yaitu:

//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(){}
};

atau sesuatu sejauh, di mana kelas bukan merupakan bagian dari templat, tetapi fungsinya?


sumber

Jawaban:

115

Dugaan Anda adalah yang benar. Satu-satunya hal yang harus Anda ingat adalah bahwa definisi templat fungsi anggota (selain deklarasi) harus dalam file header, bukan cpp, meskipun tidak harus berada di badan deklarasi kelas itu sendiri.

Tidak yakin
sumber
3
Dan juga Anda tidak dapat mengkhususkan mereka. :-(
Frank Krueger
7
Tidak sepenuhnya benar. Definisi dapat dalam file cpp, selama itu dipanggil satu kali untuk setiap parameter template unik n-uplet dari fungsi / metode non-template setelah didefinisikan.
Benoît
1
Maka "harus" saya - menyimpannya di header adalah cara paling sederhana untuk mencapai itu.
Not Sure
4
Sebenarnya, saya percaya Anda dapat secara khusus mengkhususkan mereka, tetapi Anda tidak dapat secara khusus mengkhususkan mereka. Sayangnya saya tidak tahu apakah ini adalah ekstensi khusus-kompiler, atau standar C ++.
Patrick Johnmeyer
7
Ini sebenarnya standar c ++. Anda dapat melakukan struct A {template <typename> void f (); }; template <> void A :: f <int> () {} misalnya. Anda tidak bisa mengkhususkan mereka dalam lingkup kelas, tetapi Anda bisa melakukannya dengan baik ketika dilakukan dalam lingkup namespace. (jangan bingung dengan ruang lingkup yang benar-benar dimasukkan ke dalam spesialisasi: spesialisasi masih akan menjadi anggota kelas - tetapi definisinya dilakukan dalam lingkup namespace. Seringkali ruang lingkup di mana sesuatu dimasukkan adalah sama dengan ruang lingkup sesuatu didefinisikan pada - tapi itu kadang-kadang tidak benar, seperti dalam semua kasus definisi out-of-class)
Johannes Schaub - litb
70

Lihat di sini: Templat , metode templat , Templat Anggota, Templat Fungsi Anggota

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];
}
tidak ada
sumber
contoh yang baik. tapi mengapa template <typename T> ada di dalam class definitino ... ???
Martian2049
@ Martian2049 Saya percaya ini begitu template hanya berlaku untuk fungsi anggota di dalam kelas, dan bukan kelas secara keseluruhan. Persis seperti yang diminta OP.
CBK
21

Ya, fungsi templat anggota sangat legal dan bermanfaat pada banyak kesempatan.

Satu-satunya peringatan adalah bahwa fungsi anggota template tidak bisa virtual.

Tobias
sumber
9

Cara termudah adalah dengan meletakkan deklarasi dan definisi dalam file yang sama, tetapi dapat menyebabkan file excutable yang terlalu besar. Misalnya

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

Selain itu, dimungkinkan untuk menempatkan definisi templat dalam file yang terpisah, yaitu untuk menempatkannya dalam file .cpp dan .h. Yang perlu Anda lakukan adalah secara eksplisit memasukkan contoh template ke file .cpp. Misalnya

// .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);
Hei
sumber