使用简单模板时如何修复 CLANG 中的 "undefined symbol"

How to fix "undefined symbol" in CLANG when using simple Template

我正在尝试使用模板结构实现一个简单的系统,代码非常简单并且可以用 MSVC 编译,但我不明白为什么 CLANG 会给我这个错误:"lld-link : error : undefined symbol: public: static struct FMyStruct const TSpec<1>::m_struct"

我使用 VisualStudio IDE 在 windows 64 位机器上编译,但 CLANG LLVM 作为编译器。该代码适用于 MSVC。 我将我的问题简化到最低限度,我试图将所有内容放在一个单独的 cpp 文件中,但没有结果。我还尝试了显式模板实例化。 我想符合 C++14,而不是 C++17。我尝试过的一件事是将 m_struct 成员声明为内联变量,但随后我收到此警告:"inline variables are a C++17 extension"

struct FMyStruct
{
    const int _p0;
    const int _p1;
    const int _p2;
};

template< int > struct TSpec {
    static constexpr FMyStruct m_struct = { 0, 0, 0 };
};

FMyStruct
Function( int i )
{
    return  TSpec< 1 >::m_struct;
}

int main()
{
    return 0;
}

结果:

"lld-link : error : undefined symbol: public: static struct FMyStruct const TSpec<1>::m_struct"

我希望链接器能找到符号 m_struct,因为它的定义就在它旁边...... 最奇怪的是,如果我尝试:

int
Function( int i )
{
    return  TSpec< 1 >::m_struct._p0;
}

程序可以正常编译。

编辑:我的 CLANG 版本是 9.0.0,来自官方网站 windows 的预构建分布式版本。

clang version 9.0.0 (trunk)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin

看来确实是CLANG版本的bug,感谢@Sombrero Chicken指出。

所以这绝对很奇怪,但我设法通过在模板结构定义之后添加以下内容来解决这个问题,避免了 C++17 特定的 'inline' 静态成员声明:

template< int N > const FMyStruct TSpec< N >::m_struct;

顺便说一句,它似乎与模板声明完全无关。 总而言之,它给出了可以正常编译的程序。

struct FMyStruct
{
    const int _p0;
    const int _p1;
    const int _p2;
};

template< int > struct TSpec {
    static constexpr FMyStruct m_struct = { 0, 0, 0 };
};

template< int N > const FMyStruct TSpec< N >::m_struct;

FMyStruct
Function( int i )
{
    return  TSpec< 1 >::m_struct;
}

int main()
{
    return 0;
}

我仍然不太明白为什么这是必要的,因为静态成员是结构的 public,并且是同一单元和文件的一部分;我想这是另一回事,但我想得到启发。谢谢。