0

我正在开发一个包含多个模块的项目,并且遇到很多重复符号错误。我试图创建我的项目的精简版本来诊断错误。

我有下面的代码和依赖结构。每个 .hpp 和 .tpp 文件都有标头保护,但我从 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)

基础.hpp

#pragma once

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

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

基础.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;
}

我的类.hpp

#pragma once

#include "Base.hpp"

struct MyClass
{
    void hello_myclass() const;
};

我的类.cpp

#include "MyClass.hpp"

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

主文件

#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
4

2 回答 2

2

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

void Base<int>::hello_base() const

那是您违反了单一定义规则,这会导致重复的符号链接失败。

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

于 2021-05-17T02:13:07.393 回答
1
  1. 确保在标题中使用 #ifdef XXX_H _
  2. 您不能在标头中定义变量,只能声明。
于 2021-05-17T02:02:55.800 回答