使用简单模板时如何在CLANG中修复“未定义符号”

时间:2019-06-23 15:12:37

标签: c++ c++14 llvm-clang

我正在尝试使用模板struct来实现一个简单的系统,该代码非常简单并且可以使用MSVC很好地进行编译,但是我不明白为什么CLANG会给我这个错误:“ lld-link:error:未定义的符号:public:静态结构FMyStruct const TSpec <1> :: m_struct“

我在装有VisualStudio IDE的Windows 64位计算机上进行编译,但使用CLANG LLVM作为编译器。该代码可与MSVC正常运行。 我将问题简化到最低限度,我试图将所有内容放在一个cpp文件中,但没有结果。我还尝试了显式模板实例化。 我想符合C ++ 14,不符合C ++ 17。我尝试过的一件事是将m_struct成员声明为一个内联变量,但是随后出现以下警告:“内联变量是C ++ 17扩展”

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

1 个答案:

答案 0 :(得分:1)

这确实是与CLANG版本有关的bug,感谢@Sombrero Chicken指出了这一点。

所以这绝对很奇怪,但是我设法通过在模板结构定义之后添加以下内容来避免此静态成员的C ++ 17特定的“内联”声明:

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;
}

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