gpt4 book ai didi

c++ - 由于 header 中的特化初始化而避免重复符号?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:21:10 26 4
gpt4 key购买 nike

由于我试图在 header 中提供定义,我发现了重复的符号错误。这是来自 Minimal, Complete, and Verifiable example 的错误.头文件和源文件如下所示。

$ clang++ main.cpp x.cpp y.cpp -o main.exe 2>&1 | c++filt
duplicate symbol Id<S>::id in:
/tmp/main-3f2415.o
/tmp/long long-d62c28.o
duplicate symbol Id<T>::id in:
/tmp/main-3f2415.o
/tmp/long long-d62c28.o
duplicate symbol Id<S>::id in:
/tmp/main-3f2415.o
/tmp/unsigned long long-bfa6de.o
duplicate symbol Id<T>::id in:
/tmp/main-3f2415.o
/tmp/unsigned long long-bfa6de.o
ld: 4 duplicate symbols for architecture x86_64

这里有一个类似的问题,但不涉及特化:Static member initialization in a class template .这个问题有特化,但它是针对 MSVC 而不是 Clang:How to initialize a static member of a parametrized-template class .这个问题指出将它放在源 (*.cpp) 文件中,但我们的目标是头文件避免 Clang 3.8 和 'Id<S>::id' required here, but no definition is available 警告:Where should the definition of an explicit specialization of a class template be placed in C++?

GCC、ICC、MSVC、SunCC 和 XLC 都可以初始化。 Clang 和 LLVM 给我带来了麻烦。 Clang 和 LLVM 在特化和 extern 的显式实例化方面也存在问题。 , 所以它有自己的特殊 hell 。

我们支持 C++03 到 C++17,所以我们必须小心解决方案。我天真地尝试将特化的初始化放在一个未命名的命名空间中,以防止符号转义翻译单元,但它导致了编译错误。

在 header 中初始化和特化模板类时,我们如何避免重复的符号定义?


下面是 MCVE,它是一个 cat main.cpp a.h s.h s.cpp t.h t.cpp x.cpp y.cpp .问题似乎出在 a.h 上,它提供特化和初始化;和源文件 x.cppy.cpp , 其中包括 a.h .

main.cpp

#include "a.h"
#include "s.h"
#include "t.h"

int main(int argc, char* argv[])
{
uint8_t s = Id<S>::id;
uint8_t t = Id<T>::id;
return 0;
}

a.h

#ifndef A_INCLUDED
#define A_INCLUDED

#include <stdint.h>

template <class T> class Id
{
public:
static const uint8_t id;
};

class S;
class T;

template<> const uint8_t Id<S>::id = 0x01;
template<> const uint8_t Id<T>::id = 0x02;

#endif

s.h

#ifndef S_INCLUDED
#define S_INCLUDED

class S {
public:
S();
};

#endif

s.cpp

#include "s.h"

S::S() {}

t.h

#ifndef T_INCLUDED
#define T_INCLUDED

class T {
public:
T();
};

#endif

t.cpp

#include "t.h"

T::T() {}

x.cpp

#include "a.h"

y.cpp

#include "a.h"

最佳答案

Clang/LLVM 不是问题所在。您只是遇到了未定义的行为,而无需进行任何诊断。修复很简单。您需要将您的专业放在一个翻译单元中。即,

a.cpp:

#include "a.h"

template<> const uint8_t Id<S>::id = 0x01;
template<> const uint8_t Id<T>::id = 0x02;

然后是命令行:

clang++ main.cpp a.cpp x.cpp y.cpp -o main.exe 2>&1 | c++filt

瞧。它有效。

关于c++ - 由于 header 中的特化初始化而避免重复符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47972746/

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