Std ad alanında bir şablon sınıf bildirimi nasıl iletilir?


131
#ifndef __TEST__
#define __TEST__

namespace std
{
    template<typename T>
    class list;
}

template<typename T>
void Pop(std::list<T> * l)
{
    while(!l->empty())
        l->pop();
}

#endif

ve bu işlevi ana sayfamda kullandım. Hatalar alıyorum. Tabii ki, std::list(sanırım ayırıcı) için daha fazla şablon parametresi olduğunu biliyorum . Ama bu noktanın yanı sıra. Bir şablon sınıfının tam şablon bildirimini iletmek için bunu bildirmek zorunda mıyım?

DÜZENLEME: Daha önce bir işaretçi kullanmıyordum - bu bir referanstı. İşaretçi ile deneyeceğim.


Ve liste durumunda, ikinci parametrestd::allocator<T>
nakiya

2
STL'nin ileriye dönük bildirim başlıkları içermemesinin bir gözetim olduğu düşünülebilir. Öte yandan, dosyaları o kadar sık ​​dahil edilir ki, muhtemelen derleme zamanında herhangi bir fayda sağlamaz ...
Matthieu M.

7
__TEST__ayrılmış bir tanımlayıcıdır, kullanmayın .
GManNickG

1
olası yinelenen C ++ ileri beyan sorunu
iammilind

Yanıtlar:


146

Sorun, bir şablon sınıfını ileri bildirememeniz değildir. Evet, doğru şekilde iletmek için tüm şablon parametrelerini ve varsayılanlarını bilmeniz gerekir :

namespace std {
  template<class T, class Allocator = std::allocator<T>>
  class list;
}

Ancak, böyle bir ileri bildirimde bulunmak bile namespace stdstandart tarafından açıkça yasaklanmıştır: Eklemenize izin verilen tek şey , genellikle kullanıcı tanımlı bir türdeki stdşablon uzmanlığıdırstd::less . Gerekirse başka biri ilgili metinden alıntı yapabilir.

Sadece #include <list>ve bunun için endişelenme.

Oh, tesadüfen, çift alt çizgi içeren herhangi bir isim uygulama tarafından kullanılmak üzere ayrılmıştır, bu yüzden TEST_Hbunun yerine benzeri bir şey kullanmalısınız __TEST__. Bir uyarı veya hata oluşturmaz, ancak programınızın uygulama tanımlı bir tanımlayıcıyla çakışması varsa, doğru derlenmesi veya çalıştırılması garanti edilmez: biçimsizdir . Diğerlerinin yanı sıra alt çizgi ile başlayan ve ardından büyük harfle başlayan isimler de yasaktır. Genel olarak, hangi sihirle uğraştığınızı bilmiyorsanız, işe alt çizgilerle başlamayın.


4
Bir şeyleri namespace stdbtw olarak iletmek neden yasak ?
nakiya

4
Bu yanıta ( stackoverflow.com/questions/307343/… ) ve bağlantılı haber grubu tartışmasına göz atın .
Jon Purdy

7
Jon / Nakiya, #pragma once# ifdef'ler yerine neden kullanmayalım ? Bugünlerde çoğu derleyici tarafından destekleniyor.
Mark Ingram

11
@Mark: Çünkü bu #pragma, nedeni bu. Bu bir seçenek olsa da.
Jon Purdy

2
Bu sorunun milyonlarca kopyası var. Sadece arayın: stackoverflow.com/search?q=pragma+once
Jon Purdy

20

Bu sorunu çözdüm.

C ++ (Eclipse Juno) 'da bir ağ simülasyonu için bir OSI Katmanı (kaydırıcı pencere, Seviye 2) uyguluyordum. Çerçevelerim (şablon <class T>) ve durumları (durum modeli, ileriye dönük bildirim) vardı.

Çözüm aşağıdaki gibidir:

Gelen *.cppdosya Üstbilgi dosyası içermesi gerektiğini öne sen yani

ifndef STATE_H_
#define STATE_H_
#include <stdlib.h>
#include "Frame.h"

template <class T>
class LinkFrame;

using namespace std;

template <class T>
class State {

  protected:
    LinkFrame<int> *myFrame;

}

Cpp'si:

#include "State.h"
#include "Frame.h"
#include  "LinkFrame.h"

template <class T>
bool State<T>::replace(Frame<T> *f){

Ve ... başka bir sınıf.


34
using namespaceBir başlık dosyasına herhangi bir şey koymak çok kötü bir uygulamadır çünkü bu başlık dosyasını kullanan herhangi birinin aksi takdirde geçerli olacak yerel isimleri kullanmasını engeller. Temel olarak ad alanlarının tüm noktasını yener.
Andy Dent


-5

kullanabileceğiniz sınırlı bir alternatif var

başlık:

class std_int_vector;

class A{
    std_int_vector* vector;
public:
    A();
    virtual ~A();
};

cpp:

#include "header.h"
#include <vector>
class std_int_vector: public std::vectror<int> {}

A::A() : vector(new std_int_vector()) {}
[...]

gerçek programlarda test edilmemiştir, bu yüzden mükemmel olmamasını bekleyin.

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.