2017-04-23 4 views
0

문제는 스케일 필드와 3D 벡터 필드의 그라디언트를 계산하려는 컴퓨터 그래픽 C++ 프로젝트에서 기인합니다. 우리는 그것들의 그래디언트가 다르다는 것을 알고 있습니다 : 스케일 필드는 3D 벡터 그라디언트를 가지고 3D 벡터 필드는 3x3 매트릭스 그라데이션을 가지고 있습니다. 다른 모든 코드는 동일하므로 코드를 다시 사용하기 위해 템플릿을 사용하고 있습니다. 그러나 다른 데이터 유형의 그래디언트를 계산하는 코드가 다른 멤버 함수를 특수화 할 때 문제가 발생했습니다. 최소화 된 코드는 다음과 같다 :C++ 오류 : 템플릿 클래스에 특수화 된 멤버 함수의 다중 정의이지만 실제로 한 번만 정의했습니다.

//======== Main.cpp ======== 
#include "Render.h" 
int main() {} 

//======== Render.cpp ======== 
#include "Render.h" 

//======== Render.h ======== 
#ifndef __RENDER_H__ 
#define __RENDER_H__ 
#include "VolumeGrid.h" 
#endif 

//======== VolumeGrid.h ======== 
#ifndef __VOLUMEGRID_H__ 
#define __VOLUMEGRID_H__ 

#include "Volume.h" 

template < typename U > 
class _Grid { 
public: 
    const typename GradType<U>::GType grad(const Vector& x) const; 
    U * values = nullptr; 
}; 

template <> 
const Vector _Grid<float>::grad(const Vector& x) const { 
    return Vector(); 
} 

template <> 
const Matrix _Grid<Vector>::grad(const Vector& x) const { 
    return Matrix(); 
} 

#endif 

//======== Volumn.h ======== 
#ifndef __VOLUME_H__ 
#define __VOLUME_H__ 

#include "Vector.h" 
#include "Matrix.h" 

template <typename U> 
struct GradType { 
    typedef int GType; 
}; 

template<> 
struct GradType<float> { 
    typedef Vector GType; 
}; 

template<> 
struct GradType<Vector> { 
    typedef Matrix GType; 
}; 

template< typename U > 
class Volume { 
public: 
    typedef U volumeDataType; 
    typedef typename GradType<U>::GType volumeGradType; 
}; 

#endif 


//======== Vector.h ======== 
#ifndef __VECTOR_H__ 
#define __VECTOR_H__ 

class Vector { 
public: 
    float xyz[3] = { 0,0,0 }; 
}; 

#endif 

//======== Matrix ======== 
#ifndef __MATRIX_H__ 
#define __MATRIX_H__ 

class Matrix { 
    public: 
     float m[3][3]; 
}; 

#endif 

오류 메시지는 다음과 같습니다 당신이 코드에서 볼 수 있듯이

build/Debug/GNU-Linux/Render.o: In function `Vector::Vector()': 
/home/CppApplication_1/VolumeGrid.h:19: 
multiple definition of `_Grid<float>::grad(Vector const&) const' 
build/Debug/GNU-Linux/Main.o:/home/CppApplication_1/VolumeGrid.h:19: 
first defined here 
build/Debug/GNU-Linux/Render.o: In function 
`_Grid<Vector>::grad(Vector const&) const': 
/home/CppApplication_1/VolumeGrid.h:24: 
multiple definition of `_Grid<Vector>::grad(Vector const&) const' 
build/Debug/GNU-Linux/Main.o:/home/CppApplication_1/VolumeGrid.h:24: 
first defined here 

는 다른 데이터 유형에 해당하는 두 개의 전문 grad 기능 VolumeGrid에 한 번만 정의 .h는 각각 클래스 Grid<float>Grid<Vector>의 멤버 함수로 사용됩니다. 그러나 오류 메시지에는 여러 가지 정의가 있음을 알 수 있습니다. 이 코드는 우분투 14.04 64-bit에서 C++ 11이 활성화 된 g ++ 4.8.4로 컴파일되었습니다 (Visual Studio 2015에서 잘 컴파일됩니다). 위의 코드는 Main.cpp에서 임의의 줄 (예 : #include "Render.h")을 제거하면 오류가 사라질 수 있으므로 최소화됩니다. 헤더 포함 구조 및 클래스 상속 계층 구조는 실제 프로젝트에서 사용되므로 변경해서는 안됩니다. 그렇다면 grad 기능을 전문적으로 다룰 때 문제가있는 곳과 해결 방법을 알려주십시오. 도와 주셔서 정말로 고맙습니다.

답변

4

명시 적 함수 템플릿 특수화 (템플릿 매개 변수 없음)는 실제 템플릿과 같이 암시 적으로 inline이 아닙니다.

정의를 * .cpp 파일로 이동하거나 inline으로 표시하십시오. 당신이 *의 .cpp 파일로 이동하는 경우

, 당신은 내가 인라인을 추가

template <> 
const Vector _Grid<float>::grad(const Vector& x) const; 
+0

같이 헤더 파일을 선언해야하고 그것을 작동합니다. 고마워요! – user5280911

관련 문제