与 MSVC 链接错误,但与 constexpr 的 g++ 无关
Posted
技术标签:
【中文标题】与 MSVC 链接错误,但与 constexpr 的 g++ 无关【英文标题】:Link error with MSVC but not with g++ with constexpr 【发布时间】:2018-09-25 14:57:06 【问题描述】:考虑以下代码:
#include <iostream>
struct FactoryTag
static struct Shape shape;
static struct Color color;
;
template <typename TFactory>
int factoryProducer(TFactory tag)
if constexpr (std::is_same<TFactory, FactoryTag::Shape>::value)
return 12;
else if constexpr (std::is_same<TFactory, FactoryTag::Color>::value)
return 1337;
int main()
std::cout << factoryProducer(FactoryTag::shape) << std::endl;
return 0;
它适用于g++ -std=c++1z Main.cpp
,但在 Visual Studio 中设置了 MSVC 并支持 c++17,它提供了
Error LNK2001 unresolved external symbol "public: static struct FactoryTag::Shape FactoryTag::shape" (?shape@FactoryTag@@2UShape@1@A) StaticTest C:\Users\danielj\source\repos\StaticTest\StaticTest\StaticTest.obj 1
这是 MSVC 中的错误吗?
【问题讨论】:
您可以使用static inline constexpr struct Shape shape; static inline constexpr struct Color color;
解决此问题,即为这些静态成员提供定义。
@VTT,你不需要inline
,因为constexpr
他们已经内联了。
【参考方案1】:
这是 MSVC 中的错误吗?
不,FactoryTag::shape
在这里是 odr-used 的,所以它需要一个定义(你正在复制构造它,它通过隐式生成的复制构造函数,这需要你绑定一个参考)。可以说,这也不是 gcc 中的错误,因为如果缺少定义,则会出现 no diagnostic required。
解决方案是添加定义。旧方法是:
struct FactoryTag ... ;
Shape FactoryTag::shape; // somewhere in a source file
新方法是:
struct FactoryTag
struct Shape static constexpr shape ; // implicitly inline in C++17
;
【讨论】:
我不太明白“无需诊断”是什么意思? @J.Daniel 诊断是编译器向您提供的有关您所做的不好的事情的消息(可能是错误,也可能是警告)。通常,编译器需要向您提供有关您做错的事情的消息。但有时,实际上很难弄清楚这一点——因此该标准不需要诊断。这是其中一种情况。以上是关于与 MSVC 链接错误,但与 constexpr 的 g++ 无关的主要内容,如果未能解决你的问题,请参考以下文章
constexpr 在联合中初始化结构时,msvc visual c++ 静默错误代码生成
为啥从 constexpr 引用生成的汇编代码与 constexpr 指针不同?