Topic: using non-type template parameters


Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/08/23
Raw View
>>>>> "RM" == Robert Mashlan <rmashlan@r2m.com> writes:
[...]
RM> template<class T,int N>
RM> A<T,N-1> f( A<T,N>& a )
RM> {
RM>    A<T,N-1> r;
RM>    // ...
RM>    return r;
RM> }


[...]
RM> The template function f represents a function to return the minor
RM> matrix of an element in the matrix.   I can't get this to compile --
RM> BC++ 5.0 gives the error message "Template argument must be a constant
RM> expression".   I assume that it is talking about the expression N-1 in
RM> the return type template instance.  This error message is a little
RM> confusing, because N is a constant expression, thus N-1 should be a
RM> constant expression.

Correct.

RM> I have read 14.10.2.10 of the April draft, and I have noted that is
RM> does say "Nontype parameters shall not be used in expressions in the
RM> function declaration.".    I assume that this forbids the expression
RM> in the return type.  If this is so, what is the reasoning behind this
RM> rule?  In the return type, the expression has no bearing of the
RM> deduction of the template parameters, so it shouldn't complicate the
RM> deduction process for the compiler.

I doubt (``hope that not'') that it was the intention of banning this
sort of practices. They have been documented and relied upon in
various places (e.g., Nackman & Barton's book).

RM> Now, assuming if the the f function was legal, what would be the
RM> legality of the recursive nature of the det template function?

Well, like all recursions you must stop it. The `if' statement in
det(...) does not prevent the instantiation of the functions in the
`else' clause and therefore would lead to infinite recursive
instantiations.

The classical way to stop this recursion is to provide a specialization
for N = 0. In this particular case, you'll almost certainly wish for
_partial_ specialization (because of the free T parameter).
Currently, I'm only aware of the beta HP compiler supporting that.

 Daveed


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/08/23
Raw View
In article <xso4tlu18u1.fsf@avs.cs.rpi.edu> vandevod@cs.rpi.edu (David
Vandevoorde) writes:

|> >>>>> "RM" == Robert Mashlan <rmashlan@r2m.com> writes:
|> [...]
|> RM> template<class T,int N>
|> RM> A<T,N-1> f( A<T,N>& a )
|> RM> {
|> RM>    A<T,N-1> r;
|> RM>    // ...
|> RM>    return r;
|> RM> }


|> [...]
|> RM> The template function f represents a function to return the minor
|> RM> matrix of an element in the matrix.   I can't get this to compile --
|> RM> BC++ 5.0 gives the error message "Template argument must be a constant
|> RM> expression".   I assume that it is talking about the expression N-1 in
|> RM> the return type template instance.  This error message is a little
|> RM> confusing, because N is a constant expression, thus N-1 should be a
|> RM> constant expression.

|> Correct.

|> RM> I have read 14.10.2.10 of the April draft, and I have noted that is
|> RM> does say "Nontype parameters shall not be used in expressions in the
|> RM> function declaration.".    I assume that this forbids the expression
|> RM> in the return type.  If this is so, what is the reasoning behind this
|> RM> rule?  In the return type, the expression has no bearing of the
|> RM> deduction of the template parameters, so it shouldn't complicate the
|> RM> deduction process for the compiler.

|> I doubt (``hope that not'') that it was the intention of banning this
|> sort of practices. They have been documented and relied upon in
|> various places (e.g., Nackman & Barton's book).

>From the text of the error message, I think that this is once again a
question of the compiler not taking the template argument as a constant.
See the thread just ended, and the comments from Fergus Henderson, in
this regard.  According to one interpretation, template formal
parameters are not allowed in constant expressions.  Thus, the
instantiation A<T,N-1> is illegal, because the expression N-1 contains a
template formal parameter, and is thus not a constant expression.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: rmashlan@r2m.com (Robert Mashlan)
Date: 1996/08/25
Raw View
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) wrote:

>>From the text of the error message, I think that this is once again a
>question of the compiler not taking the template argument as a constant.
>See the thread just ended, and the comments from Fergus Henderson, in
>this regard.  According to one interpretation, template formal
>parameters are not allowed in constant expressions.  Thus, the
>instantiation A<T,N-1> is illegal, because the expression N-1 contains a
>template formal parameter, and is thus not a constant expression.

If you take the whole text of 14.10.2.10,  it says:

"Nontype parameters shall not be used in expressions in the function
declaration. The type of the function template-parameter shall match
the type of the template-argument exactly."

This rule allows:

template<int i> class A { ... };

template<int i>
void f( A<i> a  )
{
   // ...
}

but it disallows:

template<int i>
void f( A<i+1> a )
{
   // ..
}

Since a non-type template parameter must be a constant expression, the
former case implies that i from the function template paremeter is a
constant expression, since that's the only thing allowed to be used as
an argument in non-type template parameters.

The latter restriction I can see as being reasonable for the template
argument deduction process, since things could really get out of hand
if you tried something like:

template<int i>
void f( A<i*i> )
{
   //...
}


   A<1> a;
   f(a);   // I am I suppose to use  f<1> or f<-1>?

The other thing which would imply that the non-type template arguments
are constant expressions inside the template is that 14.7.2 says "A
non-reference template-argument cannot have its address taken. When a
non-reference template-argument is used as an initializer for a
reference a temporary is always used."

This is the same rule used for binding references to constant
expressions, so why would a non-type template argument not be a
constant expression?

rm


---
Robert Mashlan  R2M Software  rmashlan@r2m.com
Internet Resources for Windows Developers http://www.r2m.com/windev/
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: rmashlan@r2m.com (Robert Mashlan)
Date: 1996/08/23
Raw View
Hello,

I'd like some comments on the legality of the following code according
to the current draft.

template<class T,int N>
class A {
   public:
      // ...
      T& operator()( int i, int j ) { return data[i][j]; }
   protected:
      T data[N][N];
};

template<class T,int N>
A<T,N-1> f( A<T,N>& a )
{
   A<T,N-1> r;
   // ...
   return r;
}

template<class T,int N>
T det( A<T,N>& a )
{
   if(N==1)
      return a(0,0);
   else
      return det(f(a));
}

int main(void)
{
   A<int,4> a;
   int r = det(a);
   return 0;
}

The idea behind the code is an implementation of a square matrix as
template class A, with elements of type T and of order N.

The template function f represents a function to return the minor
matrix of an element in the matrix.   I can't get this to compile --
BC++ 5.0 gives the error message "Template argument must be a constant
expression".   I assume that it is talking about the expression N-1 in
the return type template instance.  This error message is a little
confusing, because N is a constant expression, thus N-1 should be a
constant expression.

I have read 14.10.2.10 of the April draft, and I have noted that is
does say "Nontype parameters shall not be used in expressions in the
function declaration.".    I assume that this forbids the expression
in the return type.  If this is so, what is the reasoning behind this
rule?  In the return type, the expression has no bearing of the
deduction of the template parameters, so it shouldn't complicate the
deduction process for the compiler.

Now, assuming if the the f function was legal, what would be the
legality of the recursive nature of the det template function?

rm



---
Robert Mashlan  R2M Software  rmashlan@r2m.com
Internet Resources for Windows Developers http://www.r2m.com/windev/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]