C++ 是不是;用作非类型模板参数";是否隐式实例化函数模板?
我想编写一个类模板C++ 是不是;用作非类型模板参数";是否隐式实例化函数模板?,c++,language-lawyer,function-templates,non-type-template-parameter,implicit-instantiation,C++,Language Lawyer,Function Templates,Non Type Template Parameter,Implicit Instantiation,我想编写一个类模板M,它接受不完整类型C作为模板参数。 但我也希望C在最终定义时有一些特点 这个代码有保证吗 要编译(如果已定义)(标志) 如果失败的话!定义(标志) 模板结构虚拟{}; 模板 无效检查() { 静态断言(std::is_-triple_-v); } 模板 结构M:虚拟 { //static_assert(std::is_平凡_v);//错误:类型不完整 C*p; }; 结构测试; M M; int main() { 返回0; } #如果已定义(标志) 结构测试{}; #否则
M
,它接受不完整类型C
作为模板参数。
但我也希望C
在最终定义时有一些特点
这个代码有保证吗
- 要编译(如果已定义)(标志)
- 如果失败的话!定义(标志)
模板结构虚拟{};
模板
无效检查()
{
静态断言(std::is_-triple_-v);
}
模板
结构M:虚拟
{
//static_assert(std::is_平凡_v);//错误:类型不完整
C*p;
};
结构测试;
M M;
int main()
{
返回0;
}
#如果已定义(标志)
结构测试{};
#否则
结构测试{std::string非平凡成员;};
#恩迪夫
实例化点[临时点](17.7.4.1/8)
函数模板、成员函数模板或类模板的成员函数或静态数据成员的专门化可以在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于在翻译单元内具有实例化点的任何此类专门化,翻译单元的末端也被视为实例化点。类模板的专门化在翻译单元中最多有一个实例化点。任何模板的专门化都可能在多个翻译单元中有实例化点。如果两个不同的实例化点根据“一个定义”规则(6.2)赋予模板专门化不同的含义,则程序的格式不正确,不需要诊断
首先,请注意paa0的主模板是标准speak中的一个专门化。C++程序员使用它与我的经验中的标准不同。
其次,check
在程序中有两个实例化点;立刻
M<Test> m;
M;
一次在翻译单元的末尾
M
处的check
的含义与翻译单元末尾的check
的含义不同。在一个点,测试
未完成,在另一个点,测试已完成。check
的主体肯定有不同的含义
因此,您的程序格式不正确,不需要诊断。在您的例子中,格式不正确的程序恰好可以执行您想要的操作,但它(在标准下)可以编译成任何东西,或者无法编译
我怀疑这条规则背后的原因是给编译器立即实例化
check
或将其推迟到以后的自由。您不允许依赖于它实际执行检查
主体实例化的两个点中的哪一个,我怀疑M
您的代码已经是格式错误的ndr。但我不确定。我对一个涉及实例化点和编译单元末尾的子句记忆犹新,该子句旨在赋予编译器延迟实例化检查
正文的自由,但要求任一点给出相同的结果。@Yakk AdamNevraumont:我记得,类和函数的规则是不同的。类只实例化一次,而函数实例化应该“尊重”ODR(因此对于每个POI都是相同的(EOF是一个可能的POI))。因此问题在于check
,而不是M
@Jarod42,但是struct M:Dummy
上的check
的POI是M
行,不是?也就是说,如果Test
在M
之后定义的位置是,M
就可以了(其他任何事情都是疯狂的)。@Yakk AdamNevraumont:我会说M
实例化检查,对于EOF再次检查。因此,M
实例化一次,使用不完整的Test
,并检查两次,一次使用不完整的Test
,一次使用完整的Test
。
M<Test> m;