我有一些C++11模板代码,我正在尝试将其移植到Visual C++ Compiler 2015。原始代码可以正常工作,但是我需要重写它以解决constexpr的问题。
原始代码(简化示例)
然而,当我重写代码时,一些静态变量没有被初始化。尽管编译通过了。 移植后的代码(未运行)
#include <iostream>
struct String
{
static constexpr const char * value{ "STRING" };
};
template<typename Base>
class Derived
{
public:
static constexpr const char * value{ Base::value };
};
template<typename BarType>
struct Foo
{
static constexpr const char * value{ BarType::value };
};
using Bar = Derived<String>;
using FooBar = Foo<Bar>;
int main()
{
std::cout << "FooBar::value = " << FooBar::value << std::endl;
}
这将打印:
FooBar::value = STRING
然而,当我重写代码时,一些静态变量没有被初始化。尽管编译通过了。 移植后的代码(未运行)
#include <iostream>
struct String
{
static const char * value;
};
const char * String::value = "STRING";
template<typename Base>
class Derived
{
public:
static const char * value;
};
template<typename Base>
const char * Derived<Base>::value = { Base::value };
template<typename BarType>
struct Foo
{
static const char * value;
};
template<typename BarType>
const char * Foo<BarType>::value = { BarType::value };
using Bar = Derived<String>;
using FooBar = Foo<Bar>;
int main()
{
std::cout << "FooBar::value = " << FooBar::value << std::endl;
}
这将打印:
// nothing (Segmentation fault)
为什么会发生这种情况?
我该如何修复/解决它?
这可以在Clang和Visual-C++中重现,然而GCC在第二个例子中也打印出FooBar::value = STRING
。
更新:可行的解决方案
如@serge-ballesta所建议的那样。我更喜欢这个解决方案,因为它非常类似于原始代码。当constexpr成员添加到VS时,易于应用和轻松删除。
STRING
不符合您的预期吗? - Lightness Races in Orbittemplate class Derived<String>; template struct Foo<Derived<String>>;
显式实例化这两个类可以解决 segfault 的问题。 - Piotr Skotnicki