拆分内联非成员运算符的声明和定义的正确方法(链接器问题)

Proper way to split declaration and definition of inlined non member operator (linker issue)

我有一个包含 2 个项目的 visual studio 解决方案,其中一个是 静态库 。 在这个库中,我有以下 class 和一些重载的运算符(成员和非成员):

namespace Vec
{
    class Vec2
    {
     ...
      inline Vec2& operator +=(const Vec2& b);

    };
    inline Vec2 operator+(const Vec2&a, const Vec2&b);
}

.cpp文件中的定义如下:

inline Vec2& Vec2::operator +=(const Vec2& b)
    {
        this->x += b.x;
        this->y += b.y;

        return *this;
    }
inline Vec2 Vec::operator+(const Vec2& a, const Vec2& b)
    {
        return Vec2(a.x + b.x, a.y + b.y);
    }

成员运算符的所有内容都编译并且 link 正确。非成员函数没有link,错误如下:

Error 4 error LNK2019: unresolved external symbol "class Vec::Vec2 __cdecl Vec::operator+(class Vec::Vec2 const &,class Vec::Vec2 const &)" (??HVec@@YA?AVVec2@0@ABV10@0@Z) referenced in function _main

如果我将定义放在头文件中,或者将定义与声明分开但删除 内联 关键字,它 link 会成功。

我做错了什么?

What am I doing wrong?

您的错误是从声明它的 header 中省略了 inline 函数的定义。如果您在不包含定义的 cpp 文件中使用该函数,您将违反语言规则。

§7.1.2 / 4(n3242 草案)

An inline function shall be defined in every translation unit in which it is odr-used...

如果声明函数non-inline,则上述规则不适用。如果您在 header 中包含定义,则您遵守规则。

Proper way to split declaration and definition

您可以拆分它们,但不能拆分成单独的文件。

// in header

// declarations...
class Vec2
{
    Vec2& operator +=(const Vec2& b);
};
Vec2 operator+(const Vec2&a, const Vec2&b);

// definitions...
inline Vec2& Vec2::operator +=(const Vec2& b)
{
    ...
}
inline Vec2 operator+(const Vec2& a, const Vec2& b)
{
    ...
}