C++17下MSVC模板特化链接失败:MRE是否符合标准?
VTK静态库编译链接失败问题
使用Visual Studio 2022(17版本)编译VTK 9.3.1为静态库时,链接阶段报错:
vtkCommonCore-9.3.lib(vtkSMPToolsAPI.obj) : error LNK2019: unresolved external symbol "public: bool __cdecl vtk::detail::smp::vtkSMPToolsImpl<1>::IsParallelScope(void)" (?IsParallelScope@?$vtkSMPToolsImpl@$00@smp@detail@vtk@@QEAA_NXZ) referenced in function "public: bool __cdecl vtk::detail::smp::vtkSMPToolsAPI::IsParallelScope(void)" (?IsParallelScope@vtkSMPToolsAPI@smp@detail@vtk@@QEAA_NXZ)
注:编译为动态库时可正常构建。
该问题已被上报但尚未解决,现将其简化为独立的最小可复现示例(MRE)。
最小可复现示例(MRE)
当C标准设置为C17时,MinGW可正常编译运行,但MSVC出现同类链接错误:
main.obj : error LNK2019: unresolved external symbol "public: unsigned __int64 __cdecl Brick<0>::GetNumberOfSides(void)" (?GetNumberOfSides@?$Brick@$0A@@@QEAA_KXZ) referenced in function main
推测原因是编译器未将Brick<ShapeType::Circle>::GetNumberOfSides的定义放入Circle.obj目标文件,导致链接器无法找到符号。
注:将C标准改为C20时,MSVC可正常编译。
文件内容
Brick.h
#ifndef Brick_h #define Brick_h #include <cstddef> enum class ShapeType { Circle = 0, Triangle = 3, Square = 4 }; template< ShapeType Shape > class Brick { public: std::size_t GetNumberOfSides() { return static_cast< std::size_t >( Shape ); } }; #endif // Brick_h
Circle.cxx
#include "Brick.h" template<> std::size_t Brick< ShapeType::Circle >::GetNumberOfSides() { throw 0; }
main.cxx
#include <iostream> #include "Brick.h" template<> std::size_t Brick< ShapeType::Circle >::GetNumberOfSides(); int main() { Brick< ShapeType::Circle > B; try { std::cout << B.GetNumberOfSides(); } catch( ... ) { std::cerr << "Uncaught exception - terminating. "; } return 0; }
CMakeLists.txt
cmake_minimum_required( VERSION 3.12...3.29 FATAL_ERROR ) project( Toy VERSION 1.0 ) set( CMAKE_CXX_STANDARD 17 ) set( CMAKE_CXX_STANDARD_REQUIRED True ) add_executable( Toy main.cxx Circle.cxx ) target_include_directories( Toy PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} )
构建命令
mkdir build cd build cmake .. cmake --build .
核心疑问
上述最小示例是否符合C++17标准?
换句话说,这是Microsoft编译器的bug,还是MinGW(GCC)的实现过于宽松?
内容的提问来源于stack exchange,提问作者Adayah
相关产品推荐
相关产品推荐

