Large published program compilation problem

Hello,

My environment is Ubuntu 12.04. I use g++ compiler

I need to try to compile and run a C++ program devoted to a special variant of Fourier Transform: Spherical Harmonics Expansion. It takes place on a unit sphere. The source code can be had here:

http://www.codeproject.com/Articles/24428/A-Simple-Class-for-Spherical-Harmonic-Expansion

The code seems to be written with Microsoft Visual Studio in mind but I am trying to use g++. I get a number of serious errors which I do not understand how to correct. I mostly do gfortran code.

1
2
3
4
5
  /// Multiplies a SHProjection by a constant factor.
    /// This is equivalent to a scaling of the represented function.
116:=>    template < typename TReal, class TFunction, typename TScalar >
    friend const SHProjection operator * <> ( TScalar lhs, const SHProjection& rhs );


Error:
1
2
3
SHProjection.h:116:16: error: declaration of ‘class TReal’
     template < typename TReal, class TFunction, typename TScalar >
                ^


1
2
3
4
template< typename TReal >    // <== line 44
class SHProjection                    
{
public:


Error:

1
2
3
SHProjection.h:44:11: error:  shadows template parm ‘class TReal’
 template< typename TReal >
           ^


1
2
3
4
/// Multiplies a SHProjection by a constant factor.
    /// This is equivalent to a scaling of the represented function.
    template < typename TReal, class TFunction, typename TScalar >
    friend const SHProjection operator * <> ( TScalar lhs, const SHProjection& rhs );


The last line in the code above is line 117

Error:

1
2
3
SHProjection.h:117:84: error: invalid use of template-id ‘operator*<>’ in declaration of primary template
     friend const SHProjection operator * <> ( TScalar lhs, const SHProjection& rhs );
                                                                                    ^


There are a number of other errors but I hope to learn from these three samples and perhaps correct some of the rest myself.

I wonder if this code can be salvaged? Also does it make sense to proceed? If the original designer posted the code with such errors, how much is it worth?

Thanks, - Alex
Last edited on
SHProjection.h:116:16: error: declaration of ‘class TReal’
     template < typename TReal, class TFunction, typename TScalar >
                ^
This error doesn't make sense - are you sure there is not more context to this error? Did you copy and paste it in its entirety?
LB, I copied everything faithfully. It is a simple operation to copy code and errors. What do you mean by more context? Could you be more specific?
Have you tried in another compiler like clang? What version of gcc did you use?

You can try clang at http://coliru.stacked-crooked.com/
Last edited on
Here's a minimal example
1
2
3
4
5
template <class T>
class foo{
   template<class T /*T already defined*/, class Scalar>
   friend foo operator*(Scalar lhs, const foo &rhs);
};
both clang and gcc choke on that.

You issue is similar to http://stackoverflow.com/questions/1297609/overloading-friend-operator-for-template-class but I cannot generalise for the `Scalar' template parameter.

What you can do is move the definition of the friend function to be inside the class (at the point of declaration), or change `T' for another thing (but that changes the meaning)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <class T>
class foo{
private:
   T value;
   template<class Scalar> //now is just one parameter
   friend foo operator*(Scalar lhs, const foo &rhs){
      //defined here
      rhs.value; //it's friend so can access it
      return rhs;
   }

   //variant
   template<class U, class Scalar>
   friend foo<U> operator*(Scalar lhs, const foo<U> &rhs);
};

//the definition may remain untoched
template<class T, class Scalar> //the change is only needed in the declaration
foo<T> operator*(Scalar lhs, const foo<T> &rhs){
      rhs.value; //it's friend so can access it
      foo<int> a; a.value = 42; //however, it is friend of all foo, so this is valid
      return rhs;
}




Edit: I cannot download the code as it asked for a log in, this is a guess based on the error message.
Last edited on
Thanks everyone who contributed. I tried clang-3.5 and got pretty much similar errors. I also wanted to post the original source files like SHProjection.h but the post was rejected on the grounds that it was more than the max which is 8192. In fact it was about a hundred characters less. I don't know what to do at this point. With my limited experience in C++ I am looking for a "cheap" solution but it is not forthcoming.

Thanks, - Alex
> I am looking for a "cheap" solution
1
2
    template < typename TReal2, class TFunction, typename TScalar >
    friend const SHProjection operator * ( TScalar lhs, const SHProjection& rhs );
Hi Alex,

It compiles for me if I make the changes suggested above by @ne555:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ diff ../original/SHProjection.h SHProjection.h
115,116c115,116
<       template < typename TReal, class TFunction, typename TScalar >
<       friend const SHProjection operator * <> ( TScalar lhs, const SHProjection& rhs );

>     template < class TFunction, typename TScalar >
>     friend const SHProjection operator *  ( TScalar lhs, const SHProjection& rhs );
120,121c120,121
<       template < typename TReal, class TFunction, typename TScalar >
<       friend const SHProjection operator * <> ( const SHProjection& lhs, TReal rhs );

>     template < class TFunction, typename TScalar >
>     friend const SHProjection operator *  ( const SHProjection& lhs, TReal rhs );


And add typename to line 614 in SHProjection.inl:
const typename SHProjection< TReal >::SHCoefficients& coeffs = projection.m_coefficients;

HTH
norm b,

Thank you very much. I've kind of lost faith in the code, so my attention's been diverted. I really appreciate it. @ne555, thank you so much also. Now I will try to compile it.

- Alex
Last edited on
OK guys. Thank you again. The file SHProjection.h compiled nicely with the changes you suggested. Now I got two compile errors in SHProjection.inl. They are:

1
2
3
4
5
6
7
8
9
10
....$g++ main.cpp
In file included from SHProjection.h:199:0,
                 from main.cpp:1:
SHProjection.inl: In function ‘std::ostream& operator<<(std::ostream&, const SHProjection<TReal>&)’:
SHProjection.inl:614:8: error: need ‘typename’ before ‘SHProjection<TReal>::SHCoefficients’ because ‘SHProjection<TReal>’ is a dependent scope
  const SHProjection< TReal >::SHCoefficients& coeffs = projection.m_coefficients;
        ^
SHProjection.inl:615:24: error: ‘coeffs’ was not declared in this scope
  const std::size_t n = coeffs.size();                         ^
 


The code itself (those lines) is below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 template< typename TReal >
std::ostream& operator << ( std::ostream& os, const SHProjection< TReal >& projection )
{
	const SHProjection< TReal >::SHCoefficients& coeffs = projection.m_coefficients;  // <== #614
	const std::size_t n = coeffs.size();

	os << "[";
	for( std::size_t i=0; i<n; ++i )
	{
		os << coeffs[i] << ( i == n-1 ? "" : ", " );
	}
	os << "]";

	return os;
} 


Obviously I will appreciate any suggestion.

Thanks, - Alex
Why did you ignore norm b's suggestion?
norm b wrote:
And add typename to line 614 in SHProjection.inl:
const typename SHProjection< TReal >::SHCoefficients& coeffs = projection.m_coefficients;
Last edited on
Why did I ignore it? I din not ignore. I am confused. Now everything compiles, the whole project.

THANK YOU VERY MUCH. - Alex
Topic archived. No new replies allowed.