0
votes

For understanding this questions,please be sure to know the knowledge about the stateful meta programming,then we go.
Cite quotes about the point of instantiation of default arguments
[temp.point]/2

If a function template or member function of a class template is called in a way which uses the definition of a default argument of that function template or member function, the point of instantiation of the default argument is the point of instantiation of the function template or member function specialization.

If I understand correctly about the above quote,It means the POI of default argument is as the same as the POI of the function template that use the default argument(or if I misunderstand this bullet,please correct me).
Now,ready to consider below codes:

#include <iostream>
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<typename T, int N>
T show(int = add_state<N>::value) {
    return T{};
}

int main() {
    show<int, 0>();
    call(state<0>{});
}

Actually,the above code is well-formed(the result here godbolt).However,accroding to the above quote, the POI of add_state<0> would be as the same as that of show<int, 0>(),the POI of show<int, 0>() either after function main or at the end of translate unit(Perhaps,most compliers take the end of translate unit as a POI for function template),However at that point,the call of call(state<0>{}); could not find the definition of call(state<0>{}) ,so it would be ill-formed.
the result of the above code proved that the POI of add_state<0> must precede the call of call(state<0>{}),only under this situation,the definition of call(state<0>{}) can be looked up.So it confuse me,How to interpret this question,I appreciate for correct interpretaions.

1
I told it in your previous question dealing with stateful meta programing, I will repeat here. It is breaking so many things (like std::is_same_v<S<>, S<>> being false), it should proabaly considered ill-formed in general. See the question and its only answer: stackoverflow.com/questions/44267673/…CygnusX1
@CygnusX1 thanks,I just want to understand the poni of instantiation about default argument within function template,However ,the result mentioned in my question is so confusion,It driver me want to know how the complier process such code,obviously,the complier seems to do not use the rules in standard to process such code,out of curios ,I want to know how complier process themxmh0511
The point is, that it shouldn't matter how particular compilers implement their type system. The final values/types is what matters. But with stateful metaprogramming those internals come to light.CygnusX1
@CygnusX1 In other words,I want to konw that is it a defect in standard about point of instantiation of default argument or is it a compiler bug that standard does not sitpulation the implementation?xmh0511

1 Answers

0
votes

If you need to see where your template is instantiated use the disassembly debug enter image description here Looks like it is instantiated outside of main function enter image description here The code in VisualStudio is consistent with code in godbolt compiled with gcc enter image description here

Ok, that is when compiling in debug mode. In release mode it behaves differently, the inline code is replaced, or optimised up to not creating any code if function does nothing. If you declare show with __declspec(noinline) then the template looks instantiated outside main function. In other words it looks very similar to explicit instantiation outside of main function:

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;
}