gpt4 book ai didi

c++ - 即使有包含保护,链接器也会提示多重定义

转载 作者:行者123 更新时间:2023-11-28 01:40:10 25 4
gpt4 key购买 nike

我无法弄清楚为什么代码无法编译,即使我有 include guards 来防止重复编译也是如此

主类foo.h:

#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED

#include <iostream>

class Foo;

template<int TDim>
struct Foo_Helper
{
static bool Compare(const Foo& this_foo, const Foo& other_foo);
};

class Foo
{
public:
Foo(const int& Value) : mValue(Value) {}
virtual ~Foo() {}
const int& Value() const {return mValue;}
template<int TDim>
bool Compare(const Foo& rother_foo) {return Foo_Helper<TDim>::Compare(*this, rother_foo);}
private:
int mValue;
};

#endif

#include "foo.hpp"

foo.hpp 定义模板特化:

#ifndef FOO_HPP_INCLUDED
#define FOO_HPP_INCLUDED

template<>
bool Foo_Helper<1>::Compare(const Foo& this_foo, const Foo& other_foo)
{
return this_foo.Value() == other_foo.Value();
}

template<>
bool Foo_Helper<2>::Compare(const Foo& this_foo, const Foo& other_foo)
{
return this_foo.Value() == other_foo.Value();
}

#endif

两个源文件:src1.cpp:

#include "foo.h"

class Test1
{
public:
bool test()
{
Foo f1(1);
Foo f2(2);

return f1.Compare<1>(f2);
}
};

src2.cpp:

#include "foo.h"

class Test2
{
public:
bool test()
{
Foo f1(1);
Foo f2(2);

return f1.Compare<2>(f2);
}
};

CMakeLists.txt:

set(file_list
src1.cpp
src2.cpp
)

add_library(Test SHARED ${file_list})

错误信息:

Linking CXX shared library libTest.so
CMakeFiles/Test.dir/src2.cpp.o: In function `Foo_Helper<1>::Compare(Foo const&, Foo const&)':
/home/hbui/workspace/c++/multiple_definition_error/foo.hpp:7: multiple definition of `Foo_Helper<1>::Compare(Foo const&, Foo const&)'
CMakeFiles/Test.dir/src1.cpp.o:/home/hbui/workspace/c++/multiple_definition_error/foo.hpp:7: first defined here
CMakeFiles/Test.dir/src2.cpp.o: In function `Foo_Helper<2>::Compare(Foo const&, Foo const&)':
/home/hbui/workspace/c++/multiple_definition_error/foo.hpp:13: multiple definition of `Foo_Helper<2>::Compare(Foo const&, Foo const&)'
CMakeFiles/Test.dir/src1.cpp.o:/home/hbui/workspace/c++/multiple_definition_error/foo.hpp:13: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [multiple_definition_error/libTest.so] Error 1
make[1]: *** [multiple_definition_error/CMakeFiles/Test.dir/all] Error 2
make: *** [all] Error 2

我认为包含保护阻止了 foo.hpp 中的两个函数被编译。但是,看起来每个 cpp 文件都编译自己的函数。在这种情况下,如何正确定义模板专用函数?

最佳答案

header guards 阻止 header 在同一个翻译单元中被包含两次。您的问题是 Compare 特化的定义将在两个翻译单元中定义,但未标记为 inline。这意味着当链接器尝试链接由 test1.cpp 和 test2.cpp 生成的目标文件时,它会给您一个多重定义错误。如果您将特化标记为 inline,那么它们可以在两个 TU 中定义,链接器将丢弃其中一个定义:

template<>
inline bool Foo_Helper<1>::Compare(const Foo& this_foo, const Foo& other_foo)
//^^^^
{
return this_foo.Value() == other_foo.Value();
}

template<>
inline bool Foo_Helper<2>::Compare(const Foo& this_foo, const Foo& other_foo)
//^^^^
{
return this_foo.Value() == other_foo.Value();
}

关于c++ - 即使有包含保护,链接器也会提示多重定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47529840/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com