문제

방금 이 새 클래스를 만들었습니다.

//------------------------------------------------------------------------------
#ifndef MULTITHREADEDVECTOR_H
#define MULTITHREADEDVECTOR_H
//------------------------------------------------------------------------------
#include <vector>
#include <GL/GLFW.h>
//------------------------------------------------------------------------------
template<class T>
class MultithreadedVector {

    public:

        MultithreadedVector();

        void push_back(T data);

        void erase(typename std::vector<T>::iterator it);

        std::vector<T> get_container();
    private:

        std::vector<T> container_;
        GLFWmutex th_mutex_;


};
//------------------------------------------------------------------------------
#endif // MULTITHREADEDVECTOR_H_INCLUDED
//------------------------------------------------------------------------------

클래스의 정의:

//------------------------------------------------------------------------------
#include "MultithreadedVector.h"
//------------------------------------------------------------------------------
using namespace std;
//------------------------------------------------------------------------------
template<class T>
MultithreadedVector<T>::MultithreadedVector() {

    th_mutex_ = glfwCreateMutex();
}

template<class T>
void MultithreadedVector<T>::push_back(T data) {

    glfwLockMutex(th_mutex_);
    container_.push_back(data);
    glfwUnlockMutex(th_mutex_);

}

template<class T>
void MultithreadedVector<T>::erase(typename vector<T>::iterator it) {

    glfwLockMutex(th_mutex_);
    container_.erase(it);
    glfwUnlockMutex(th_mutex_);
}

template<class T>
vector<T> MultithreadedVector<T>::get_container() {


    return container_;

}

이제 문제는 내 코드에서 다른 클래스의 정적 멤버로 사용하려고 할 때입니다.

// VehicleManager.h
#ifndef MULTITHREADEDVECTOR_H
#define MULTITHREADEDVECTOR_H

#include "MultithreadedVector.h"
#include "Vehicle.h"
class Foo {

   public:
     // stuffs
   private:
     static MultithreadedVector<Vehicle> vehicles_; 
     ...
}

#endif

그런 다음 내부 :VehicleManager.cpp

#include "VehicleManager.h"

MultithreadedVector<Vehicle> VehicleManager::vehicles_;

void VehicleManager::Method() {

  Vehicle vehicle;
  VehicleManager::vehicles_.push_back(vehicle);

}

하지만 컴파일되지 않습니다.(, 매번 이 오류 메시지가 나타납니다.

C:\***\VehicleManager.cpp|188|undefined reference to `MultithreadedVector<Vehicle>::push_back(Vehicle)'|

특히 VehicleManager.cpp의 전역 범위에서 정적 클래스 멤버를 정의한 이유를 정말로 이해하지 못합니다.

추신:저는 Code::Blocks를 사용하고 있습니다.

감사해요 !

도움이 되었습니까?

해결책

이것이 클래스 템플릿 구현을 CPP 파일로 맹목적으로 이동할 때 일어날 일입니다.

해당 작업을 수행하려면 클래스 템플릿을 인스턴스화하고 CPP 파일에 어떤 유형을 인스턴스화 할 것인지 정확히 알아야합니다.

이 경우 이것을 CPP 파일에 넣습니다.

template class MultithreadedVector<Vehicle>;

CPP 파일은 알아야합니다 Vehicle 그 다음에.

다른 팁

대부분의 C++ 컴파일러에서는 템플릿 선언과 템플릿 정의를 분리하는 것을 허용하지 않습니다.템플릿 클래스의 전체 정의를 .h 및 .cpp 파일로 분할하는 것이 아니라 단일 .h 파일에 넣어야 합니다.

템플릿 구현 전체 코드는 템플릿을 사용하는 시점에서 컴파일러에 표시되어 템플릿을 인스턴스화하고 나중에 연결할 수있는 객체 코드로 컴파일 할 수 있어야합니다.

템플릿이 선언 된 것과 동일한 헤더 파일에서 템플릿 코드를 정의하십시오.

템플릿을 사용하는 방법이 두 가지 있다고 생각합니다.

  1. 임의의 순응 유형 세트에 대한 일반 코드 제공
  2. 고정 유형 세트에 대한 일반 코드 제공

두 번째의 경우 템플릿을 헤더에 넣을 필요가 없습니다. 템플릿을 사용하는 유형을 사용하여 미리 알고 있으므로 정확하게 알 수 있습니다. 클래스 템플릿의 멤버 함수 또는 링커 오류없이 별도의 번역 장치에서 함수 템플릿을 잘 정의 할 수 있습니다. 어떤 사람들은 다른 사람들에게 이것이 불가능하다고 계속 가르치고 있으며, 이것으로 문제를 혼동합니다.

그러나 나는 그것이 선언과 정의를 다른 번역 단위로 분리할지 여부에 따라이 두 경우에 달려 있다고 생각합니다.

  • Case 1을 사용하려면 항상 헤더에 정의를 원합니다 (특수 명명 된 파일에 포함 되든 .ipp, .tcc 또는 무엇이든). 이 경우에도 선언과의 정의를 분리하는 것을 지원하는 하나의 C ++ 프론트 엔드 만 알고 있습니다. export. 이 키워드는 일부의 키워드로 간주되며 대부분의 컴파일러는이를 구현하지 않습니다.

  • 그리고 Case 2를 사용하려면 정의를 헤더에 넣는 것이 좋지 않습니다. 왜냐하면 그렇게 할 이유가 없기 때문입니다. 고정 된 유형 세트에 필요한 기능과 클래스를 명시 적으로 인스턴스화합니다. 이 두 번째 시나리오에서는 템플릿을 사용하여 중복 코드를 유지하기 위해 부담으로부터 자신을 절약하고 경우에 따라 일부 유형에 대해 특별한 동작을 도입 할 수있는 옵션을 열어줍니다.

시나리오는 분명히 사례 1 상황이므로 정의를 헤더에 넣어야합니다.

VehicleManager.h에 복사 및 붙여 넣기 오류가있는 것 같습니다.

#ifndef MULTITHREADEDVECTOR_H
#define MULTITHREADEDVECTOR_H

이는 클래스 FOO가 정의되는 헤더 파일의 포함을 금지합니다.

대부분의 경우 CPP 파일에 템플릿 구현을 쓸 수 없습니다. 컴파일러가 제대로 인스턴스화 할 수 있도록 템플릿 구현을 헤더 파일로 이동하십시오.

다른 답변과는 별도로 :

당신은 보호해야합니다 get_container() 또한. 이 방법은 기본적으로 복사합니다 container_ 요소와 따라서 보호해야합니다.

template<class T>
vector<T> MultithreadedVector<T>::get_container() 
{
    return container_;
}

어떤 면에서 템플릿은 일종의 고급 특수 매크로입니다.실제로 하려는 것처럼 보이는 것처럼 템플릿 정의를 별도로 컴파일할 수는 없습니다.

대부분의 사람들에게 이는 테플레이트 정의를 선언과 분리하는 데 신경을 쓰지 않는다는 의미입니다.나에겐 동료가 한 명 있는데, 그 사람은 이것을 한 단계 더 발전시킵니다, 그리고 별거를 거부합니다 비템플릿 정의와 선언도 마찬가지입니다.

선언에서 템플릿 정의를 넣으려면 몇 가지 옵션이 있습니다.

첫 번째 옵션은 C++ "내보내기" 키워드를 사용하는 것입니다.겉으로는 간단해 보이는 이 솔루션의 문제점은 다음과 같습니다. 아무도 지지하지 않아.컴파일러 작성자가 구현하기에는 너무 어렵습니다.

두 번째 옵션은 세 번째 유형의 파일, 선언의 경우 종종 ".ipp" 태그가 지정됩니다.여기서 중요한 점은 여전히 ​​"#included"가 되어야 하는 파일이지만 별도의 파일이므로 ".cpp" 파일에만 포함하면 된다는 것입니다.단일 프로그램에서 둘 이상의 ".cpp" 파일에 ".ipp"를 #include하는 경우 내 링커가 이를 좋아하지 않는다는 것을 알았습니다. 따라서 하나를 포함자로 선택해야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top