नाम स्थान std में टेम्पलेट वर्ग कैसे घोषित करें?


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

और मेरे मुख्य में उस फ़ंक्शन का उपयोग किया। मुझे त्रुटियाँ मिलती हैं। निश्चित रूप से, मुझे पता है कि std::list(मुझे लगता है कि आवंटनकर्ता) के लिए अधिक टेम्पलेट पैरा हैं । लेकिन वो बात मुद्दे से अलग है। क्या मुझे इसे घोषित करने में सक्षम होने के लिए टेम्प्लेट क्लास की पूर्ण टेम्पलेट घोषणा को जानना होगा?

संपादित करें: मैं पहले एक पॉइंटर का उपयोग नहीं कर रहा था - यह एक संदर्भ था। मैं सूचक के साथ इसे आज़माऊँगा।


और सूची के मामले में, दूसरा पैरामीटर एक डिफ़ॉल्ट पैरामीटर है जो हैstd::allocator<T>
nakiya

2
एक व्यक्ति यह देख सकता है कि एसटीएल में आगे की घोषणा करने वाले हेडर नहीं हैं। दूसरी ओर, इसकी फाइलें इतनी बार शामिल की जाती हैं कि यह संकलन समय पर शायद कोई लाभ नहीं देगी ...
Matthieu M.

7
__TEST__एक आरक्षित पहचानकर्ता है, इसका उपयोग न करें
GMNNGG

जवाबों:


146

समस्या यह नहीं है कि आप किसी टेम्पलेट वर्ग को अग्रेषित-घोषित नहीं कर सकते। हां, आपको सभी टेम्प्लेट मापदंडों और उनकी चूक को जानने की जरूरत है ताकि वे इसे सही ढंग से अग्रेषित करने में सक्षम हो सकें:

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

लेकिन इस तरह के एक आगे की घोषणा namespace stdकरने के लिए मानक द्वारा स्पष्ट रूप से निषिद्ध है: केवल एक चीज जिसे आप डालने की अनुमति देते हैं , stdएक टेम्पलेट विशेषज्ञता है , आमतौर std::lessपर उपयोगकर्ता-परिभाषित प्रकार पर। यदि आवश्यक हो तो कोई और संबंधित पाठ का हवाला दे सकता है।

बस #include <list>और इसके बारे में चिंता मत करो।

ओह, संयोग से, डबल-अंडरस्कोर वाले किसी भी नाम को कार्यान्वयन द्वारा उपयोग के लिए आरक्षित किया गया है, इसलिए आपको TEST_Hइसके बजाय कुछ का उपयोग करना चाहिए __TEST__। यह एक चेतावनी या एक त्रुटि उत्पन्न करने वाला नहीं है, लेकिन यदि आपके कार्यक्रम में कार्यान्वयन-परिभाषित पहचानकर्ता के साथ झड़प है, तो इसे सही तरीके से संकलित या चलाने की गारंटी नहीं है: यह बीमार है । निषिद्ध भी एक अंडरस्कोर के साथ शुरू होने वाले नाम हैं जिनके बाद एक कैपिटल लेटर होता है, दूसरों के बीच। सामान्य तौर पर, अंडरस्कोर के साथ चीजों को शुरू न करें, जब तक कि आप नहीं जानते कि आप किस जादू के साथ काम कर रहे हैं।


4
namespace stdBtw में चीजों को आगे घोषित करने के लिए क्यों निषिद्ध है ?
नकीया

4
इस उत्तर को देखें ( stackoverflow.com/questions/307343/… ) और जुड़े हुए समाचार समूह चर्चा।
जॉन पुरडी

7
जॉन / नाकिया, #pragma once# ifdef's के बजाय क्यों नहीं उपयोग करते हैं । यह इन दिनों अधिकांश कंपाइलरों द्वारा समर्थित है।
मार्क इनग्राम

11
@ मर्क: क्योंकि यह है #pragma, इसीलिए। हालांकि यह एक विकल्प है।
जॉन प्यूडी

2
उस सवाल के डुप्लिकेट के निशान हैं। बस खोज: stackoverflow.com/search?q=pragma+once
जॉन पर्पडी

20

मैंने उस समस्या को हल किया।

मैं C ++ (ग्रहण जूनो) में नेटवर्क सिमुलेशन के लिए OSI लेयर (स्लाइडर विंडो, लेवल 2) लागू कर रहा था। मेरे पास फ्रेम (टेम्पलेट <class T>) और उसके राज्य (राज्य पैटर्न, आगे की घोषणा) थे।

समाधान इस प्रकार है:

में *.cppफ़ाइल, आप हैडर फ़ाइल को शामिल करना चाहिए कि आप आगे, यानी

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:

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

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

और ... एक और वर्ग।


34
using namespaceहेडर फाइल में किसी को भी डालना एक बहुत ही बुरा अभ्यास है क्योंकि यह किसी को भी उस हेडर फाइल का उपयोग करने से रोकता है जो स्थानीय नामों का उपयोग करने में सक्षम होता है जो अन्यथा मान्य होगा। यह मूल रूप से नेमस्पेस के पूरे बिंदु को हरा देता है।
एंडी डेंट

10

फ़ॉरवर्ड डिक्लेरेशन में निर्दिष्ट पूरा टेम्प्लेट तर्कों की सूची होनी चाहिए।


-5

एक सीमित विकल्प है जिसका आप उपयोग कर सकते हैं

शीर्ष लेख:

class std_int_vector;

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

सीपीपी:

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

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

वास्तविक कार्यक्रमों में परीक्षण नहीं किया गया है, इसलिए उम्मीद करें कि यह बिल्कुल सही न हो।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.