Sign in to follow this  
kRogue

potentiall dumb C++ question

Recommended Posts

all irght, I would like to know what I am doing wrong, this compiles and works as it should:
template<typename T, unsigned int N>
class vecN
{
public:
  T elements[N];
  //stuff
};

template<typename T, unsigned int N>
inline ostream &operator<<(ostream &ostr, const vecN<T,N> &in)
{
  unsigned int i;

  ostr << "(";
  for(i=0;i<N;++i)
    {
      if(i!=0)
	ostr << ", ";
      ostr << in[i];

    }

  ostr <<")";

  return ostr;
}


//somewhere in a function
vecN<float,3> it;

cout << it;





but the following the compiler pukes on:
template<typename T>
class FunctionFactory
{ 
//lots of stuff
public:
 class Function
 {
 //stuff
 public:
 //stuff 
   ostream &Print(ostream &ostr) const 
   { 
      //stuff
    }
 };
}

template<typename T>
inline ostream &operator<<(ostream &ostr, const typename FunctionFactory<T>::Function &obj)
{
  return obj.Print(ostr);
}


//somewhere in main...
FunctionFactor<float>::Function handy
//blah
cout << handy //compile fails here!




the exact compile message is: "error: no match for ‘operator<<’ in ‘std::cout << handy" and then proceeds to list all the ways that the << operator is overloaded. but it works jsut fine if I have
handy.Print(cout);





what am I doing wrong? (compiler g++ v4.02)

Share this post


Link to post
Share on other sites
just an addendum, the following will wok though:


typedef complex<float> dataType;

inline ostream &operator<<(ostream &ostr, const FunctionFactory<dataType>::Function &obj)
{
return obj.Print(ostr);
}

//later
FunctionFactory<dataType>::Function handy;

//later still
cout << handy;


Share this post


Link to post
Share on other sites
Is that code copy-and-pasted? If so, you're missing a semi-colon on the class just before you define your operator<<. If it's not a copy-and-paste, it should be (who knows what small mistake you could be overlooking in the actual code).

Share this post


Link to post
Share on other sites
Replace:

inline ostream &operator<<(ostream &ostr, const typename FunctionFactory<T>::Function &obj)

with:

inline ostream &operator<<(ostream &ostr, const class FunctionFactory<T>::Function &obj)

and it will compile OK. Alternatively (and probably better) put the function inside the class:

template<typename T>
class FunctionFactory
{
//lots of stuff
public:
class Function
{
//stuff
public:
//stuff
ostream &Print(ostream &ostr) const
{
//stuff
return ostr;
}
friend ostream &operator<<(ostream &ostr, Function &obj)
{
return obj.Print(ostr);
}
};
};


Skizz

PS: 'inline' is a fairly redundant keyword.

Share this post


Link to post
Share on other sites
well using



template<typename T>
inline ostream &operator<<(ostream &ostr, const class FunctionFactory<T>::Function &obj)
{
return obj.Print(ostr);
}



still gets rejected by the compiler (i.e. it does not believe that the function exists) but the second suggestion does work. Also, I don't _think_ that inline is redundant in the case for template stuff: template stuff (I imagine) gets generated for each source file (thus the linker does not really see DOSomething<float> for example) but I _think_ that unless you put inline there, then the compiler wil have exactly one copy of DOSomething<float> for each soruce file that uses it and generate a "jmp" to that address, where as inline _suggests_ to the compiler to inline the function...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this