Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是不是;用作非类型模板参数";是否隐式实例化函数模板?_C++_Language Lawyer_Function Templates_Non Type Template Parameter_Implicit Instantiation - Fatal编程技术网

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;