VC++ 2015 error: "an expression involving objects with internal linkage cannot be used as a non-type argument"

VC++ 2015 error: "an expression involving objects with internal linkage cannot be used as a non-type argument"

以下 sample code 在 VC++ 2019、clang++ 和 g++ 中编译,但在 VC++ 2015 中不编译。

namespace ns
{
    template<const char* str>
    struct Foo
    {
    };
    
    static const char name[] = "Test";
    Foo<name> foo;
}

int main()
{
}

VC++ 2015 有任何解决方法吗?我假设代码符合要求,但 VC++ 2015 有一个错误已在 VC++ 2019 中修复。我会迁移到 VC++ 2019,但我的公司建立在 VC++ 2015 年。

如评论中所述,问题在于 VS-2015 不符合 C++11 标准,这是实现您显示的代码所必需的。

查看 this report 中对问题的描述,我发现解决该问题的唯一方法是删除声明中的 staticconst 限定符name。以下编译甚至使用 VS-2010 构建工具(我无法在我的 PC 上访问 VS-2015 工具,但是,因为这适用于 VS-2010 和 VS-2019,我认为它也可以VS-2015).

namespace ns {
    template<const char* str>
    struct Foo {
    };

    char name[] = "Test"; // Adding either "static" or "const" causes C2970
    Foo<name> foo;
}

int main()
{
}

此解决方法是否适合您的需求还有待观察。

MSVC 2015 不完全支持 C++11,non-type 带有内部链接的模板参数是 C++11 特性的一个例子,VC+ + 直到版本 14.14 (VS 2017 15.8) 才支持。

我可以想到 3 个解决方案:

  • 通过从 char name[]
  • 中删除 static const 说明符,不要使用带有内部链接的模板参数
  • 将编译器升级到 VC++ 14.20+ (MSVC 2019)
  • 使用特征检测and/or条件编译

关于条件编译,可以这样实现:

#if !defined(_MSC_VER) || _MSC_VER > 1914 // this part can be in a global config.h
#  define INTERNAL static const
#else
#  define INTERNAL 
#endif

namespace ns
{
    template<const char* str>
    struct Foo
    {};
    
    INTERNAL char name[] = "Test";
    Foo<name> foo;
}

int main()
{
}