네임 스페이스 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
STL에 순방향 선언 헤더가 포함되어 있지 않다고 감독하는 것으로 간주 할 수 있습니다. 다른 한편으로, 그 파일은 종종 컴파일 시간에 아무런 이익을 얻지 못할 정도로 포함되어 있습니다 ...
Matthieu M.

7
__TEST__예약 된 식별자이므로 사용하지 마십시오 .
GManNickG

답변:


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로 물건을 전달하는 것이 왜 금지 됩니까?
nakiya

4
이 답변 ( stackoverflow.com/questions/307343/… )과 연결된 뉴스 그룹 토론을 확인하십시오.
Jon Purdy

7
Jon / Nakiya, #ifdef #pragma once대신 사용 하지 않는 것이 좋습니다. 요즘 대부분의 컴파일러에서 지원합니다.
Mark Ingram 8

11
@Mark :이기 때문에 그렇습니다 #pragma. 옵션이지만.
Jon Purdy

2
그 질문에 대한 중복 된 내용이 있습니다. 검색 만하면됩니다 : stackoverflow.com/search?q=pragma+once
만하세요

20

나는 그 문제를 해결했다.

C ++ (Eclipse Juno)의 네트워크 시뮬레이션을 위해 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헤더 파일에 파일을 넣는 것은 해당 헤더 파일을 사용하는 모든 사람이 유효한 로컬 이름을 사용할 수 없도록하기 때문에 매우 나쁜 습관입니다. 기본적으로 네임 스페이스의 전체 지점을 물리칩니다.
Andy Dent

10

정방향 선언에는 완전한 템플릿 인수 목록이 지정되어 있어야합니다.


-5

사용할 수있는 제한적인 대안이 있습니다

헤더:

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()) {}
[...]

실제 프로그램에서 테스트되지 않았으므로 완벽하지 않을 것으로 예상하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.