Sign in to follow this  
chaospilot

C++ Template Issues

Recommended Posts

chaospilot    122
I'm having template issues. I have a Profile class which stores ordered pairs of double (time) and T (Matrix/double/int/bool/Quaternion/etc). I have a host of other functions that are working, but the following two (and slight variations on these two) arent working. I get a "error C2660: 'std::list<_Ty>::sort' : function does not take 1 arguments" when I try and call the function pmin, and the same with merge when I try to call it. HOWEVER, I don't get any errors when I dont try and call the functions. What gives? Code as follows. template <typename T> class Profile { private: list<pair<double, T>> data; public: friend const T pmin(const Profile<typename T>& profIn) { Profile<T> temp = profIn; temp.data.sort(profValLesser); return temp.data.front().second; } friend const Profile<T> mergeProfiles(const Profile<typename T>& prof1, const Profile<typename T>& prof2) { Profile<T> newProf; newProf.data.merge(prof1.data, profTimeLesser); newProf.data.merge(prof2.data, profTimeLesser); return newProf; } }

Share this post


Link to post
Share on other sites
chaospilot    122
Right, forgot to throw these down:

/* used to sort Profiles pairs by time */
template<typename T> bool profTimeLesser(pair<double, T> elem1, pair<double, T> elem2) {
return elem1.first < elem2.first; }

/* used to sort Profiles pairs by value */
template<typename T> bool profValLesser(pair<double, T> elem1, pair<double, T> elem2) {
return elem1.second < elem2.second; }

Share this post


Link to post
Share on other sites
Crypter    748

list<pair<double, T>> data;

Put a space between the two '>'s:

list<pair <double, T> > data;

C++ interprates >> as a right bit-shift operator,
reguardless of its synthax use.

Share this post


Link to post
Share on other sites
chaospilot    122
Fixed that and it still doesnt work... I've actually done this everywhere and it works okay on MSVS 2005.To clarify I have the following things tested and they work fine:

void addData(const pair<double, T>& pairIn) {
data.push_back(pairIn);}

void addData(const double tIn, const T& valIn) {
data.push_back(make_pair(tIn, valIn));}

const T getLastValue(void) {
_ASSERTE(data.size()>0);
if(data.size()>0)
return data.back().second;
else return data.front().second;}

const size_t size(void) {
return size(data); }

const pair<double, T> operator()(const size_t i) {
_ASSERTE(i<=data.size() && i>=1);
if(i<=data.size() && i>=1)
{
size_t add;
list<pair<double, T>>::iterator lIt = data.begin();
for(add=1; add<i; add++)
lIt++;
return *lIt;
}
else
return make_pair(0,0);}

const Profile operator=(const Profile& other) {
this->data = other.data;
return *this;}

friend const Profile operator-(Profile &A) {
list<pair<double, T>>::iterator lIt = A.data.begin();
for(lIt; lIt != A.data.end(); lIt++)
(*lIt).second = -(*lIt).second;
return A;}

friend const Profile operator-(const Profile &A, const Profile &B) {
return (A + (-B));}


friend const bool operator==(const Profile &A, const Profile &B) {
list<pair<double, T>>::const_iterator aIt = A.data.begin();
list<pair<double, T>>::const_iterator bIt = B.data.begin();
for(aIt; aIt != A.data.end(); aIt++) {
if(*aIt != *bIt)
return false;
bIt++;
}
return true;}

Share this post


Link to post
Share on other sites
Crypter    748
Besides the missing semicolen at the end of your class ( I assume its
a typo in the post) your code compilies fine for me. (MSVC++ 2005)

Share this post


Link to post
Share on other sites
Deyja    920
First, Crypter is right about the >>s. The compiler should interpret this as operator>>. However, MSVC++ 8.0 has an option that changes this behavior, and you obviously have it turned on, else that code wouldn't compile at all.

Second, you only get the error when actually calling the function because template functions are not compiled if they aren't actually called.

Finally, I believe the actual error within pmin function is that the compiler is unable to resolve the type of the argument you give it, gives up, and selects the non-template overload instead. Try explicitly specifying the template argument, such that the call becomes "temp.data.sort(profValLesser<T>);". profValLesser is a template; profValLesser<T> is a predicate. (Change the other function that does not work in the same way.)

Share this post


Link to post
Share on other sites
Zahlman    1682
Just a quick comment on style:

Quote:
Original post by chaospilot

friend const T pmin(const Profile<typename T>& profIn)
{
Profile<T> temp = profIn;
temp.data.sort(profValLesser);
return temp.data.front().second;
}


IF you are goint to make a copy *anyway*, it is simpler to just pass by value and use the implicit copy:


// Oh, and we don't need 'typename' inside the template brackets here.
friend const T pmin(Profile<T> temp)
{
temp.data.sort(profValLesser);
return temp.data.front().second;
}


BUT, we can in fact do much better, because there's no need to sort the whole list if we just need the smallest element:


friend const T pmin(const Profile<T>& profIn)
{
return std::min_element(profIn.data.begin(), profIn.data.end())->second;
}


And for that matter, why not just make it a member function? (With appropriate const correctness, of course.)


const T pmin() const {
return std::min_element(data.begin(), data.end())->second;
}


As for mergeProfiles, I think we could do that at least as easily with a constructor:


// The first set doesn't have to "merge", because there are no elements in yet
// for it to merge with. So we just copy them implicitly, via the initialization
// list...
Profile(const Profile<T>& a, const Profile<T>& b) : data(a.data) {
data.merge(b.data, profTimeLesser);
}

Share this post


Link to post
Share on other sites
chaospilot    122
Awesome. Worked great, with some minor modifications. I really appreciate the style advice. It's almost as valuable as the content itself because I'm an Aerospace Engineer learning C++ and my advisor doesn't catch style issues in my thesis code.

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