重复符号错误 - 我的包含是否正确?

Duplicate Symbols Error - Am I doing my includes right?

我正在处理一个包含多个模块的项目,但出现了很多重复符号错误。我试图创建一个 stripped-down 版本的项目来诊断错误。

我有下面的代码和依赖结构。每个 .hpp 和 .tpp 文件都有 header 守卫,但我从 MyClass.cpp 和 main.cpp.

得到重复的符号错误

我的包含结构是否正常,有什么想法可以修复错误吗?

CMakeLists.txt

cmake_minimum_required(VERSION 3.18.0)
project("duplicate symbols" LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
add_executable(main main.cpp MyClass.cpp)

Base.hpp

#pragma once

template <typename T>
struct Base { void hello_base() const; };

#include "Base.tpp"
#include "BaseSpec.hpp"

Base.tpp

#pragma once

#include <iostream>

template <typename T>
void Base<T>::hello_base() const { std::cout << "hello base" << std::endl; }

BaseSpec.hpp

#pragma once

template <>
struct Base<int> { void hello_base() const; };

#include "BaseSpec.tpp"

BaseSpec.tpp

#pragma once

#include <iostream>

void Base<int>::hello_base() const
{
    std::cout << "Hello base int" << std::endl;
}

MyClass.hpp

#pragma once

#include "Base.hpp"

struct MyClass
{
    void hello_myclass() const;
};

MyClass.cpp

#include "MyClass.hpp"

void MyClass::hello_myclass() const
{
    std::cout << "hello myclass" << std::endl;
}

main.cpp

#include "MyClass.hpp"

int main() {}

错误信息是:

duplicate symbol 'Base<int>::hello_base() const' in:
    CMakeFiles/main.dir/main.cpp.o
    CMakeFiles/main.dir/myclass.cpp.o
  1. 确保在 header
  2. 中使用 #ifdef XXX_H_
  3. 不能在header中定义变量,只能声明。

两个 .cpp 文件都间接地包含 BaseSpec.tpp,它定义了:

void Base<int>::hello_base() const

这违反了单一定义规则,导致重复符号 link 失败。

删除 BaseSpec.tpp,并将其替换为具有相同内容的 .cpp 文件,应该可以消除 linkage 错误。