You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CLion编译C++项目时已添加对应源文件仍报undefined reference to `vec3::length() const`错误求助

解决 undefined reference to vec3::length() const 链接错误

这个问题的根源非常明确:你把inline函数的定义放在了.cpp文件中,而非头文件内。

在C++的规则里,inline函数的定义必须出现在每一个调用它的编译单元(简单来说就是每个用到这个函数的.cpp文件)中。当你在vec3.cpp里定义inline double vec3::length() const时,编译main.cpp的阶段,编译器只能看到vec3.h里的函数声明,看不到具体实现,它会默认这个函数在其他地方有外部链接的实现。但因为inline关键字的特性,链接器处理vec3.cpp时,不会保留这个inline函数的符号(inline函数默认是内部链接),最终就出现了链接时找不到符号的错误。

两种可行的解决方案:

方案1:把inline函数的定义移到头文件中

你可以直接把inline函数的实现写在vec3.h的类内部,或者类外部的头文件区域(记得保留inline关键字):

// vec3.h
#ifndef RAY_TRACING_CPP_VEC3_H
#define RAY_TRACING_CPP_VEC3_H
#include <cmath> // 必须包含这个头文件,否则sqrt等函数会报错

struct vec3 {
    double x;
    double y;
    double z;
    vec3(double x, double y, double z) : x(x), y(y), z(z) {}
    vec3() : x(0.0), y(0.0), z(0.0) {}
    explicit vec3(double x) : x(x), y(x), z(x) {}

    // 直接在类内定义inline函数
    inline double norm2() const {
        return x * x + y * y + z * z;
    }
    inline double length() const {
        return sqrt(norm2());
    }
    inline double dot(const vec3& another) const {
        return x * another.x + y * another.y + z * another.z;
    }
    inline vec3 cross(const vec3& another) const {
        return { y * another.z - z * another.y, z * another.x - x * another.z, x * another.y - y * another.x };
    }
    inline vec3 normalize() const {
        auto len = length();
        return *this / len; // 这里注意:你还需要重载vec3与double的除法运算符,否则此处也会报错
    }

    vec3 exp() const;
    vec3 pow(double param) const;
};

#endif //RAY_TRACING_CPP_VEC3_H

之后修改vec3.cpp,只保留非inline的函数实现:

#include "vec3.h"
#include <cmath>

vec3 vec3::exp() const {
    return {std::exp(x), std::exp(y), std::exp(z)};
}
vec3 vec3::pow(double param) const {
    return {std::pow(x, param), std::pow(y, param), std::pow(z, param)};
}

方案2:去掉inline关键字

如果你不想把函数定义放在头文件里,直接移除vec3.h和vec3.cpp中的inline关键字,让这些函数变成普通的外部链接函数:

// vec3.h
// 移除所有inline关键字
double norm2() const;
double length() const;
double dot(const vec3& another) const;
vec3 cross(const vec3& another) const;
vec3 normalize() const;
// vec3.cpp
// 同样移除inline关键字
double vec3::norm2() const {
    return this->x * this->x + this->y * this->y + this->z * this->z;
}
double vec3::length() const {
    return sqrt(norm2());
}
// ... 其他函数同理移除inline

另外提醒:你的vec3::normalize()函数里用到了*this / len,但目前代码中没有重载vec3与double的除法运算符,这个后续也会触发编译错误,记得补充对应的运算符重载逻辑。

你的CMakeLists.txt配置是完全没问题的,已经正确包含了vec3.cpp,无需修改。

内容的提问来源于stack exchange,提问作者IceWired

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:37:50