2017-04-23 30 views
0

問題出在計算機圖形C++項目中,我想計算比例域和3D矢量域的梯度。我們知道它們的梯度是不同的:比例場具有3D矢量梯度,而3D矢量場具有3×3矩陣梯度。由於所有其他代碼都是相同的,我正在使用模板來重新使用代碼。但是我遇到了專門的成員函數中的一個問題,它有不同的代碼來計算不同數據類型的梯度。最小化的代碼如下: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>的成員函數。但是,錯誤消息表明它們有多個定義。該代碼使用g ++ 4.8.4編譯,在ubuntu 14.04 64位上啓用C++ 11(它在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

相關問題