Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.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++_Templates_Language Lawyer - Fatal编程技术网

C++ 关于函数模板使用的默认参数的实例化点的一些混淆

C++ 关于函数模板使用的默认参数的实例化点的一些混淆,c++,templates,language-lawyer,C++,Templates,Language Lawyer,为了理解这些问题,请务必了解关于有状态元编程的知识,然后我们开始。 引用有关默认参数实例化点的引用 如果以使用该函数模板或成员函数的默认参数定义的方式调用类模板的函数模板或成员函数,则默认参数的实例化点就是函数模板或成员函数的实例化点 如果我正确理解上述引用,则表示默认参数的POI与使用默认参数的函数模板的POI相同(或者如果我误解了此项目符号,请更正)。 现在,准备考虑下面的代码: #包括 模板 结构状态{ 朋友自动呼叫(状态); }; 模板 结构添加状态{ 朋友自动呼叫(状态){ 返回N;

为了理解这些问题,请务必了解关于有状态元编程的知识,然后我们开始。
引用有关默认参数实例化点的引用

如果以使用该函数模板或成员函数的默认参数定义的方式调用类模板的函数模板或成员函数,则默认参数的实例化点就是函数模板或成员函数的实例化点

如果我正确理解上述引用,则表示默认参数的POI与使用默认参数的函数模板的POI相同(或者如果我误解了此项目符号,请更正)。
现在,准备考虑下面的代码:

#包括
模板
结构状态{
朋友自动呼叫(状态);
};
模板
结构添加状态{
朋友自动呼叫(状态){
返回N;
}
静态常数int值=N;
};
模板
T显示(int=add_state::value){
返回T{};
}
int main(){
show();
调用(状态{});
}
实际上,上面的代码是格式良好的(这里的结果)。但是,根据上面的引用,
add_state
的POI将与
show()
的POI相同,
show()
的POI在
函数main
之后或在翻译单元的末尾(也许,大多数编译器将translate单元的结尾作为函数模板的POI),但是在这一点上,
call(state{});
的调用找不到
call(state{})
的定义,因此它的格式不正确。

上述代码的结果证明,
add_state
的POI必须在
call(state{})
的调用之前,只有在这种情况下,
call(state{})的定义
可以查到。所以我很困惑,如何解释这个问题,我感谢您的正确解释。

如果您需要查看模板的实例化位置,请使用反汇编调试 看起来它是在主函数之外实例化的 VisualStudio中的代码与使用gcc编译的代码一致

好的,这是在调试模式下编译时发生的。在发布模式下,它的行为不同,内联代码被替换,或者如果函数不执行任何操作,则内联代码被优化为不创建任何代码。如果使用u declspec(noinline)声明show,则模板看起来在主函数外部实例化。 换句话说,它看起来非常类似于主函数之外的显式实例化:

using namespace std;
template<int N> struct state {
    friend auto call(state<N>);
};
template<int N> struct add_state {
    friend auto call(state<N>) {
        return N;
    }
    static const int value = N;
};
template struct add_state<0>; //<-- instantiated here
int main()
{
    call(state<0>{});
    return 0;
}
使用名称空间std;
模板结构状态{
朋友自动呼叫(状态);
};
模板结构添加状态{
朋友自动呼叫(状态){
返回N;
}
静态常数int值=N;
};

template struct add_state;//我在上一个关于有状态元编程的问题中告诉过它,我将在这里重复。它破坏了很多东西(比如
std::is_same\u v
being
false
),一般来说,它应该被认为是格式不正确的。请看问题及其唯一的答案:@CygnusX1谢谢,我只是想了解函数模板中默认参数实例化的poni,但是,我问题中提到的结果太混乱了,它让我想知道编译器是如何处理这些代码的,显然,complier似乎不使用标准中的规则来处理这样的代码,出于好奇,我想知道编译器是如何处理它们的问题是,特定的编译器如何实现它们的类型系统并不重要。最终的值/类型才是重要的。但通过有状态元编程,这些内部的东西会被发现。@CygnusX1换句话说,我想知道这是标准中关于默认参数实例化点的缺陷,还是标准没有操作实现的编译器错误?谢谢,但问题是关于defualt参数的POI,defualt参数的POI与使用defualt参数的函数模板的POI相关,以及defualt参数与标准所说的不一致…@jackX这不是实例化的默认参数点。这是默认参数模板实例化或类型创建。换句话说,它是创建代码的地方,而不是在运行时初始化值的地方。@jackX从元编程的角度讲,是模板点实例化可能永远不会发生。当编译器隐式检测到需要执行实例化时,就会生成实例化。编译器隐式生成的代码与显式实例化生成的代码完全相同。但有时我们可以改为执行显式实例化。这将强制编译器生成代码。是的,关键点是NT是C++标准,默认参数模板的实例化点与使用默认参数模板的函数模板实例化点相同,因此可观察的行为与标准一致。