You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:09:51