none
A Couple Template Questions

    Question

  • Hi folks,

     

    I have a couple questions about templates.  I'm using Visual C++ 2005  Express Edition 8.0.50727.762.

     

    Is there a reason why this compiles fine:
    ------------------------------------------------
    template <typename T, int I>
    struct C1 {};

    template <template <typename T, int I> class C1>
    struct C2 {};

    int main (int argc, char * argv[])

     C2<C1> TEST;

     return 0;
    }
    ------------------------------------------------

    But this does not (replaced class C1 with typename C1):
    ------------------------------------------------
    template <typename T, int I>
    struct C1 {};

    template <template <typename T, int I> typename C1>
    struct C2 {};

    int main (int argc, char * argv[])

     C2<C1> TEST;

     return 0;
    }
    ------------------------------------------------
    Error   1       error C2988: unrecognizable template declaration/definition     j:\test\main.cpp    9
    Error   2       error C2059: syntax error : '<L_TEMPLATEDECL>'                  j:\test\main.cpp    9
    Error   3       error C2143: syntax error : missing ';' before '<end Parse>'    j:\test\main.cpp    9
    ------------------------------------------------

    And this does not (replaced int I with T I):
    ------------------------------------------------
    template <typename T, T I>
    struct C1 {};

    template <template <typename T, T I> class C1>
    struct C2 {};

    int main (int argc, char * argv[])

     C2<C1> TEST;

     return 0;
    }
    ------------------------------------------------
    Error   1       error C3201: the template parameter list for class template 'C1' does not match the template parameter list for template parameter 'C1'    j:\test\main.cpp    9 
    ------------------------------------------------

    Saturday, January 06, 2007 3:44 PM

Answers

  •  Suncho wrote:

    template <typename T, int I>
    struct C1 {};

    template <template <typename T, int I> typename C1>
    struct C2 {};

    int main (int argc, char * argv[])
    {
     C2<C1> TEST;

     return 0;
    }
    ------------------------------------------------
    Error   1       error C2988: unrecognizable template declaration/definition     j:\test\main.cpp    9
    Error   2       error C2059: syntax error : '<L_TEMPLATEDECL>'                  j:\test\main.cpp    9
    Error   3       error C2143: syntax error : missing ';' before '<end Parse>'    j:\test\main.cpp    9
    ------------------------------------------------

    The C++ standard specifices how template parameters may be defined:

    14.1 Template parameters [temp.param]

    The syntax for template-parameters is:

    template-parameter:
        type-parameter
        parameter-declaration

    type-parameter:
        class identifieropt
        class identifieropt = type-id
        typename identifieropt
        typename identifieropt = type-id
        template < template-parameter-list > class identifieropt
        template < template-parameter-list > class identifieropt = id-"class" keyword to be used.

     Suncho wrote:

    And this does not (replaced int I with T I):
    ------------------------------------------------
    template <typename T, T I>
    struct C1 {};

    template <template <typename T, T I> class C1>
    struct C2 {};

    int main (int argc, char * argv[])
    {
     C2<C1> TEST;

     return 0;
    }
    ------------------------------------------------
    Error   1       error C3201: the template parameter list for class template 'C1' does not match the template parameter list for template parameter 'C1'    j:\test\main.cpp    9
    ------------------------------------------------

    This should not, and does not cause a compile error on VC++ 8 (2005) with the SP1 beta installed.

    (Note: the forum is unable to make sense of the formatting here, but we'll just have to live with that)

    Saturday, January 06, 2007 4:04 PM
    Moderator
  • Wow, thanks for your quick response!


    The C++ standard specifices how template parameters may be defined:

    14.1 Template parameters [temp.param]

    The syntax for template-parameters is:

    template-parameter:
        type-parameter
        parameter-declaration

    type-parameter:
        class identifieropt
        class identifieropt = type-id
        typename identifieropt
        typename identifieropt = type-id
        template < template-parameter-list > class identifieropt
        template < template-parameter-list > class identifieropt = id-"class" keyword to be used.


    Then on the next line it says:
    There is no semantic difference between class and typename in a template-parameter.

    At least that's what it says in the 2006-11-03 draft.  I dunno if that changed.


    This should not, and does not cause a compile error on VC++ 8 (2005) with the SP1 beta installed.


    Wow you're right.  I thought I had the same version of VC++ 8 on both of my machines.  My bad.  (I guess I'll upgrade the other one.)

    Saturday, January 06, 2007 4:37 PM
  • This is not ambiguous: the first rule is a syntactic rule (the 'class' token is the only token the compiler can accept) and hence it has overrules the later semantic rule ('class' and 'typename' have the same semantic meaning in template parameters).
    Wednesday, January 10, 2007 6:28 PM
    Moderator

All replies

  •  Suncho wrote:

    template <typename T, int I>
    struct C1 {};

    template <template <typename T, int I> typename C1>
    struct C2 {};

    int main (int argc, char * argv[])
    {
     C2<C1> TEST;

     return 0;
    }
    ------------------------------------------------
    Error   1       error C2988: unrecognizable template declaration/definition     j:\test\main.cpp    9
    Error   2       error C2059: syntax error : '<L_TEMPLATEDECL>'                  j:\test\main.cpp    9
    Error   3       error C2143: syntax error : missing ';' before '<end Parse>'    j:\test\main.cpp    9
    ------------------------------------------------

    The C++ standard specifices how template parameters may be defined:

    14.1 Template parameters [temp.param]

    The syntax for template-parameters is:

    template-parameter:
        type-parameter
        parameter-declaration

    type-parameter:
        class identifieropt
        class identifieropt = type-id
        typename identifieropt
        typename identifieropt = type-id
        template < template-parameter-list > class identifieropt
        template < template-parameter-list > class identifieropt = id-"class" keyword to be used.

     Suncho wrote:

    And this does not (replaced int I with T I):
    ------------------------------------------------
    template <typename T, T I>
    struct C1 {};

    template <template <typename T, T I> class C1>
    struct C2 {};

    int main (int argc, char * argv[])
    {
     C2<C1> TEST;

     return 0;
    }
    ------------------------------------------------
    Error   1       error C3201: the template parameter list for class template 'C1' does not match the template parameter list for template parameter 'C1'    j:\test\main.cpp    9
    ------------------------------------------------

    This should not, and does not cause a compile error on VC++ 8 (2005) with the SP1 beta installed.

    (Note: the forum is unable to make sense of the formatting here, but we'll just have to live with that)

    Saturday, January 06, 2007 4:04 PM
    Moderator
  • Wow, thanks for your quick response!


    The C++ standard specifices how template parameters may be defined:

    14.1 Template parameters [temp.param]

    The syntax for template-parameters is:

    template-parameter:
        type-parameter
        parameter-declaration

    type-parameter:
        class identifieropt
        class identifieropt = type-id
        typename identifieropt
        typename identifieropt = type-id
        template < template-parameter-list > class identifieropt
        template < template-parameter-list > class identifieropt = id-"class" keyword to be used.


    Then on the next line it says:
    There is no semantic difference between class and typename in a template-parameter.

    At least that's what it says in the 2006-11-03 draft.  I dunno if that changed.


    This should not, and does not cause a compile error on VC++ 8 (2005) with the SP1 beta installed.


    Wow you're right.  I thought I had the same version of VC++ 8 on both of my machines.  My bad.  (I guess I'll upgrade the other one.)

    Saturday, January 06, 2007 4:37 PM
  •  Suncho wrote:

    Then on the next line it says:
    There is no semantic difference between class and typename in a template-parameter.

    At least that's what it says in the 2006-11-03 draft.  I dunno if that changed.

    It's perhaps not the best choice of words, since most popuplar compilers (all that I've tried) implement their template support by the first rule.

    Saturday, January 06, 2007 5:06 PM
    Moderator
  • Yeah... If I were a compiler writer and I found the standard to be ambiguous in some way, I'd err on the side of consistency with the rest of the language and not consistency with other compilers.  But that's just me.
    Saturday, January 06, 2007 9:45 PM
  • This is not ambiguous: the first rule is a syntactic rule (the 'class' token is the only token the compiler can accept) and hence it has overrules the later semantic rule ('class' and 'typename' have the same semantic meaning in template parameters).
    Wednesday, January 10, 2007 6:28 PM
    Moderator
  •  Jonathan Caves - MSFT wrote:
    This is not ambiguous: the first rule is a syntactic rule (the 'class' token is the only token the compiler can accept) and hence it has overrules the later semantic rule ('class' and 'typename' have the same semantic meaning in template parameters).

    While I agree (and couldn't possibly disagree) that the syntactic rule is the one to follow, I also understand why 14.1.2 is causes confusion. I even seem to recall seeing popular books which fail to comment on the matter.

    Wednesday, January 10, 2007 6:41 PM
    Moderator
  • Thanks Jonathan.  That's the answer I was looking for.
    Thursday, January 11, 2007 3:09 AM