Как исправить «неопределенный символ» в CLANG при использовании простого шаблона - PullRequest
2 голосов
/ 23 июня 2019

Я пытаюсь реализовать простую систему, используя шаблонную структуру, код очень прост и прекрасно компилируется с MSVC, но я не могу понять, почему CLANG выдает мне эту ошибку: "lld-link: error: undefined symbol: public: статическая структура FMyStruct const TSpec <1> :: m_struct "

Я компилирую на машине с 64-битной Windows с IDE VisualStudio, но 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 Ответ

1 голос
/ 23 июня 2019

Это действительно похоже на ошибку, связанную с версией CLANG, спасибо @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;
}

Я все еще не совсем понимаю, почему это необходимо, поскольку статический член является открытым для структуры и является частью того же модуля и файла; Я думаю, это другое дело, но я хотел бы быть просветленным. Спасибо.

...