On Tue, May 31, 2016 at 1:10 PM, Nemo Yu <
mzer...@gmail.com> wrote:
> template<typename...> struct test
> {
> using ok_type = int;
> template<typename...> struct error_type {};
>
> using ok = typename test<int>::ok_type; // OK
> using error = typename test<int>::template error_type<int>; // Error
> };
>
You're trying to instantiate the definition of a template (by
accessing its nested type/template) that you're not done defining -
why would you expect that to work?
[NOTE: we have a special rule for considering the class complete in
certain contexts that lexically might appear within the class
definition - within those - and only those contexts - can constructs
be parsed and semantically analyzed as if the class's definition is
complete, those contexts do not alter the layout of the class or
change the nature (e.g. type) of member entitites -- a member type
alias is not one of them]
> 1) I test both MSVC and Clang, just got errors.
> 2) I searched on StackOverflow and CppReference, got nothing but some vague
> conclusions:
>
> A relative discussion without any answer:
>
>
https://stackoverflow.com/questions/28715062/implicit-instatiation-of-the-template-within-its-own-definition
>
> Something changed since C++11:
>
>> An explicit instantiation declaration (an extern template) prevents
>> implicit instantiations: the code that would otherwise cause an implicit
>> instantiation has to use the explicit instantiation definition provided
>> somewhere else in the program (typically, in another file: this can be used
>> to reduce compilation times)(since C++11)
>
>
Not sure I see any connection to explicit instantiation declarations
or definitions here.
>
http://en.cppreference.com/w/cpp/language/class_template
>
> -----------------------------------------------------------------------------------------------------
>
> My question is: what does the standard prevent? Implicit instantiations of a
> template class which is inside another template class, or implicit
> instantiations of template classes from their definitions(I don't think that
> makes sense, see the example below).
>
> Example:
>
> template<typename...> struct s {};
> template<typename T, typename...Ts> struct s<bT, Ts...>: s<Ts...> {};
>
Note, S<Ts...> within the base specifier of the definition of your
partial specialization is a dependent construct - i.e. you don't know
the actual type of its template arguments,( just that there are some
placeholders there that will be replaced with actual types at some
point after all templates have been completely defined), as opposed to
the test<int> above - so the base-specifier does not trigger any
instantiations - If you did use a non-dependent template-id i.e.
s<int, char> within the base specifier, it would try and use the
partial-specialization in its own recursive instantiation which should
be an error (but s<> would not since it would have to use the primary
template, which is complete at that point).
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to
std-discussio...@isocpp.org.
> To post to this group, send email to
std-dis...@isocpp.org.
> Visit this group at
>
https://groups.google.com/a/isocpp.org/group/std-discussion/.