【发布时间】:2019-09-16 09:07:44
【问题描述】:
我想强制模板实例化。
以下代码在 g++ (http://coliru.stacked-crooked.com/a/33986d0e0d320ad4) 上工作 (打印 1)。
但是,它在 Visual C++ (https://rextester.com/WGQG68063) 上打印错误的结果 (0)。
#include <iostream>
#include <string>
template <int& T>struct NonTypeParameter { };
//internal implementation
int lala=0;
template <typename T> struct Holder{
static int init;
};
template <typename T> int Holder<T>::init = lala++;
//tool for user
template <typename T> struct InitCRTP{
using dummy=NonTypeParameter<Holder<T>::init>;
};
class WantInit : public InitCRTP<WantInit>{};//user register easily
int main(){
std::cout << lala << std::endl;
}
它是 Visual C++ 编译器的错误,还是一种未定义的行为?
如果是 Visual C++ 错误,如何解决它(同时仍然保持美观)?
编辑:按照 Max Langhof(和许多人)的建议更改类 -> 结构。谢谢。
赏金原因
通过 StoryTeller 和 Maxim Egorushkin 的相反解决方案以及他们的深入讨论(谢谢!),这听起来像是 C++ 规则的模糊区域。
如果是 Visual C++ 错误,我希望问题足够确定以报告。
此外,我仍然希望有一个很好的解决方法,因为这种技术对于自定义类型 ID 生成非常有用。显式实例化不是那么方便。
注意:我将赏金授予Kaenbyou Rin,因为对我来说,这很容易理解。
这并不意味着其余的答案不太正确或不太有用。
我仍然不确定哪个是正确的。读者应谨慎行事。
为了安全起见,我假设我只是不能使用该功能(目前)。感谢大家。
【问题讨论】:
-
注意:"minimal reproducible example" 中的 "minimal" 并不代表 "使用尽可能少的空格和换行符" ;) 另外,请不要仅仅因为您希望它看起来像 Java 就按行执行
public:- 这绝对不是“美丽的”。考虑使用struct而不是class,例如Holder获取其成员的默认公开可见性。 -
我个人认为Allman style 比所有将左大括号保持在同一行的变体更具可读性(因此更“漂亮”)。没有可用的官方统计数据,但这似乎是大多数人的意见,尤其是在 C++ 和 C 编码人员中。
-
Godbolt 链接为方便起见:godbolt.org/z/THyLe1
-
显式使用类可能会给你想要的结果(需要自己测试,没有可用的MSVC)。您是否知道如果您在不同的编译单元中应用此模式,这些初始化发生的顺序是未指定的?因此,如果您只想为您的课程设置唯一的 id,那很好,如果您想要一些特定的顺序,那么您就出局了。
-
一般建议:否定 id 有意义吗?如果不是,我希望
unsigned int明确表达这一点。
标签: c++ visual-c++ g++ c++17 template-instantiation