Bir C ++ şablon sınıfı bildirmek nasıl iletilir?


107

Aşağıdaki gibi bir şablon sınıfı verildiğinde:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

Birisi bu sınıfı bir başlık dosyasında nasıl ilan edebilir?

Yanıtlar:


109

Bunu şu şekilde yaparsın:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings;

template<typename Type, typename IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

Varsayılanın gerçek tanımda değil ileriye dönük bildirimde olduğuna dikkat edin.


Öntanımlıları tanımında listelenmiş olan bir sınıfı ileriye doğru bildirmek mümkündür. Cevabımı gör.
Elliott

Katılmıyorum. Standart şöyle der: "Bir şablon parametresine aynı kapsamdaki iki farklı bildirimle varsayılan bağımsız değişkenler verilmemelidir" . Ve sadece ilk bildirimde temerrütler hakkında hiçbir şey bulamadım. Ayrıca tanımdaki ileri bildirime ve varsayılanlara sahip kod başarıyla derlenir ve çalıştırılır. Ne iddia ettiğinizden emin misiniz? Standarttan bir teklif verebilir misiniz?
oleksijp

@Elliott Doğru gibi görünüyor. Standart [17.1.9] diyor ki: "Bir varsayılan şablon-argüman olabilir bir şablon bildirimde belirteceği." Olmamalı ama olabilir. Dolayısıyla neden diğer yanıtların ilk beyanda olması gerektiğini iddia ettiğini anlamıyorum.
oleksijp

Ve tanımda temerrütlere sahip olmak çok daha uygun görünüyor.
oleksijp

8

Bir şablon için varsayılan bağımsız değişkenleri yalnızca şablonun ilk bildirimi için bildirebilirsiniz. Kullanıcıların bir sınıf şablonunu iletmesine izin vermek istiyorsanız, bir yönlendirme başlığı sağlamalısınız. Varsayılanları kullanarak başkasının sınıf şablonunu bildirmek istiyorsanız, şansınız kalmaz!


Öntanımlıları tanımında listelenmiş olan bir sınıfı ileriye doğru bildirmek mümkündür. Cevabımı gör.
Elliott

Katılmıyorum. Standart şöyle der: "Bir şablon parametresine aynı kapsamdaki iki farklı bildirimle varsayılan bağımsız değişkenler verilmemelidir" . Ve sadece ilk bildirimde temerrütler hakkında hiçbir şey bulamadım. Ayrıca tanımdaki ileri bildirime ve varsayılanlara sahip kod başarıyla derlenir ve çalıştırılır. Ne iddia ettiğinizden emin misiniz? Standarttan bir teklif verebilir misiniz?
oleksijp

5

Sen edebilirsiniz kimin tanım varsayılan argümanlar bildiren bir templated sınıf bildirmek, ancak tanım tanıtıldı kadar sınıfına atıfta herhangi bir zaman kendisine ait tüm argümanları içermelidir.

Örneğin. std::vectorDahil etmeden kullanalım (ikinci argüman std::vectorvarsayılan olarak tanımlanmıştır):

namespace std
{
    template<typename, typename>
    class vector;
}

#include <iostream>

template <typename S, typename T>
void Foo (const std::vector<S,T> & vector)
{
    std::cout << "do vector stuff, eg., display size = "
        << vector.size() << std::endl;
}

template <typename T>
void Foo (const T & t)
{
    std::cout << "do non-vector stuff..." << std::endl;
}

Daha sonra vektörü eklemeden kullanabiliriz , örneğin:

int main ()
{
    Foo(3);
}

... Ya da birlikte kullanabiliriz std::vector, örneğin:

#include <vector>

// Now the compiler understands how to handle
// std::vector with one argument
// (making use of its default argument)

int main ()
{
    Foo(std::vector<int>(3));
}

Standartları kontrol etmedim, ancak bu işe yarıyor clang/ gccsonuna -std=c++98kadar çalışıyor -std=c++17, yani resmi olarak bir standart değilse, resmi olmayan bir şekilde öyle görünüyor.


Belki boş açılı parantezleri unutursunuz Foo<> foo;.
oleksijp
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.