我今天遇到了一个相当奇怪的问题。我有一个针对 SSE 优化的数学库,因此几乎所有功能都被声明为内联。为简化起见,我将仅使用一类 Vector3 来解释该问题:
Vector3 在 Vector3.h 中声明,如下所示:
#ifndef VIRTUS_VECTOR3_H
#define VIRTUS_VECTOR3_H
#ifndef VEC3INLINE
#if(_DEBUG)
#define VEC3INLINE inline
#else
#define VEC3INLINE __forceinline
#endif
#endif
namespace Virtus {
struct Vector3
{
union
{
struct { f32 x,y,z; };
f32 v[3];
};
Vector3(void);
Vector3(const Vector3& rhs);
Vector3(f32 xx, f32 yy, f32 zz);
VEC3INLINE Vector3& operator=(const Vector3& rhs);
VEC3INLINE Vector3 operator+(f32 rhs) const;
VEC3INLINE Vector3 operator-(f32 rhs) const;
VEC3INLINE Vector3 operator*(f32 rhs) const;
VEC3INLINE Vector3 operator/(f32 rhs) const;
VEC3INLINE Vector3& operator+=(f32 rhs);
VEC3INLINE Vector3& operator-=(f32 rhs);
...
#include "vector3.inl"
#endif
在 vector3.inl 中,我继续定义所有函数
namespace Virtus {
Vector3::Vector3(void)
: x(0.0f), y(0.0f), z(0.0f)
{
}
Vector3::Vector3(const Vector3& rhs)
: x(rhs.x), y(rhs.y), z(rhs.z)
{
}
Vector3::Vector3(f32 xx, f32 yy, f32 zz)
: x(xx), y(yy), z(zz)
{
}
VEC3INLINE Vector3& Vector3::operator=(const Vector3& rhs)
{
memcpy(v, rhs.v, sizeof(v));
return *this;
}
...
然后,我将所有数学对象包含在一个名为 math.h 的文件中
#ifndef VIRTUS_MATH_H
#define VIRTUS_MATH_H
#include "vector2.h"
#include "vector3.h"
#include "vector4.h"
#include "matrix4.h"
#include "primesearch.h"
namespace Virtus
{
class MathException
{
public:
enum ErrorCode
{
PRIME_SEARCH_INVALID_ELEMENTS,
PRIME_SEARCH_UNSUFFNUM_PRIMES
};
MathException(ErrorCode code) : m_Error(code) {}
ErrorCode What(void) const { return m_Error; }
private:
ErrorCode m_Error;
};
} // namespace virtus
#endif // Include Guard
并且 math.h 包含在我的预编译头文件中(precompiled.h aka stdafx.h)
我使用 Visual Studio 2008,它应该会自动从构建过程中排除 .inl 文件。
这是我得到的链接器错误:
错误 1 错误 LNK2005: "public: __thiscall Virtus::Vector3::Vector3(void)" (??0Vector3@Virtus@@QAE@XZ) 已在 precompiled.obj main.obj Virtus 中定义
我尝试了几乎所有可以想象的方式来解决这个问题,比如手动从构建中排除所有 inl 文件;在预编译文件中不包括 math.h,但只在我需要的地方(在这种情况下,我会收到类似的已定义链接器错误);从 inl 扩展名更改为 cpp 扩展名,依此类推。我能够修复它的唯一方法是使用 #pragma once 而不是包含警卫。所以我目前最好的猜测是它与预编译头文件和包含保护的组合有关,但我不确定如何解决这个问题。
帮助将不胜感激!