[cfe-dev] default arguments cannot be added to an out-of-line definition of a member of a class template

Jonathan Sauer jonathan.sauer at gmx.de
Tue Jul 19 08:33:24 PDT 2011


Hello,

>   While trying to compile ccp4 with clang, I ran into the following error in the test case...
> 
> ------------- outofline.cpp --------------------
> template <typename realnum>
> class covar_matrix
> {
>  public:
> 
>        void SetZeroRows(int,int,int,int,int,int);      // specifies the order numbers of rows(=columns) for which the covariances should be 0.
> 
>  private:
> 
> };
> 
> 
> 
> // defines zero rows. If the first argument is negative, resets all no non-zero.
> template <typename realnum>
> void covar_matrix<realnum>::SetZeroRows( int r1=-1, int r2=-1, int r3=-1, int r4=-1, int r5=-1, int r6=-1 )
> {
>  int r[6] = {r1,r2,r3,r4,r5,r6};
>  int i=0;
> }
> 
> ------------------------------------------------
> 
> [MacPro:~] howarth% clang -c outofline.cpp
> outofline.cpp:16:46: error: default arguments cannot be added to an out-of-line definition of a member of a class template
> void covar_matrix<realnum>::SetZeroRows( int r1=-1, int r2=-1, int r3=-1, int r4=-1, int r5=-1, int r6=-1 )
> [...]
> 
> I assume this isn't a bug in clang. If so, what is the proper solution? Is it this change?

It is not a clang bug, at least not from my reading of the standard (FDIS 8.3.6p4: Adding default arguments later on is
only valid with *non-template* functions. Here we have a function template, since SetZeroRows is part of a class template).

The solution is to add the default parameters (the "-1" in your example) to the declaration of the function and to remove
them from its definition. This compiles with the current clang:

template <typename realnum>
class covar_matrix
{
 public:

       void SetZeroRows(int = -1,int = -1,int = -1,int = -1,int = -1,int = -1);      // specifies the order numbers of rows(=columns) for which the covariances should be 0.

 private:

};

// defines zero rows. If the first argument is negative, resets all no non-zero.
template <typename realnum>
void covar_matrix<realnum>::SetZeroRows( int r1, int r2, int r3, int r4, int r5, int r6 )
{
 int r[6] = {r1,r2,r3,r4,r5,r6};
 int i=0;
}


> // defines zero rows. If the first argument is negative, resets all no non-zero.
> template <typename realnum>
> void covar_matrix<realnum>::SetZeroRows( int r1, int r2, int r3, int r4, int r5, int r6 )
> {
>  int r[6] = {r1,r2,r3,r4,r5,r6};
>  int i=0;
>  r1=-1;
>  r2=-1;
>  r3=-1;
>  r4=-1;
>  r5=-1;
>  r6=-1;
> }

This most likely does not what you want: It does not specify default parameters, but sets r0-6 to -1 after
using them to initialize r.

In my opinion, this is a bug in ccp4. You should file a bug report there (with the above solution).


Hope that helps,
Jonathan





More information about the cfe-dev mailing list