Sign in to follow this  

template classes and member functions

This topic is 4019 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is it possible with a template class to lock access to certain functions and data members dependent on what type the class has been instanced as? I have a template array class with functions for finding the SD, Mean, Error in Mean, Mode, Median, etc. I obviously want these accessible to numeric instances (double, float, etc.) but not to character based such as string or char. Is it possible to do this or not?

Share this post


Link to post
Share on other sites
Yes, it is possible. Consider the std::list::sort function: it expects the contained type to have a comparison operator (or the user to provide a comparison operator for the sort). If it doesn't, then the sort function cannot be used.

If the template parameter cannot be used to compute a mean, the template will not be compiled and the user will check the documentation for why this happened, and he will find out that his type did not support the corresponding operations.

Share this post


Link to post
Share on other sites
Quote:
Original post by Alexistran
Okay second question. Given that it is possible. How do I do it?


The beatiful thing is, you don't need to do anything about it. If the template parameter provides the operators/functions required for doing something, then the function will be instantiated and can be used, and if the parameter doesn't provide the operators/functions required, then the function cannot be used.

So write your function, and let the compiler sort out the rest.

Share this post


Link to post
Share on other sites
It happens automatically. If a member of your templated class uses T in a particular way, and you try to use it with a T which can't be used in that way, the compiler will give an error. Example:


template<typename T>
class Sum<T>
{
public:
Sum() { }

Add(const T& val) { sum += val; }
const T& Get() const { return sum; }

private:
T sum;
};

int main()
{
Sum<int> a; // fine!
Sum<double> b; // sure!
Sum<void*> c; // hell, even this!

a.add(3); // works
b.add(2); // works
c.add(0); // ERROR: void*'s can't be added to each other
}





Share this post


Link to post
Share on other sites
Quote:
Original post by Alexistran
Okay second question. Given that it is possible. How do I do it?


The compiler does it for you [smile]

Your functions will make use of various operators that will not be found in user defined classes, so they will not compile. Built in number types will work ( char included ) along with any other type with all the math operators overloaded.


Share this post


Link to post
Share on other sites
Or you can be a little more clever:
#include <numeric>
#include <string>
#include <vector>
#include <boost/type_traits.hpp>

template < typename T >
class ArrayBase
{

public:

typedef typename std::vector< T >::const_iterator const_iterator;

const_iterator begin()
{
return array_.begin();
}

const_iterator end()
{
return array_.end();
}

std::size_t size() const
{
return array_.size();
}

protected:

ArrayBase()
{
}

~ArrayBase()
{
}


private:

std::vector< T > array_;

};

template < typename T, bool is_arithmetic = boost::is_arithmetic< T >::value >
class Array
:
public ArrayBase< T >
{
};

template < typename T >
class Array< T, true >
:
public ArrayBase< T >
{

public:

T mean() const
{
return std::accumulate(begin(), end(), T()) / size();
}

};

int main()
{
Array< float > float_array;
Array< std::string > string_array;
float_array.mean();
string_array.mean(); //error
}

Σnigma

Share this post


Link to post
Share on other sites
Okay that's fine for the functions but what about data members? I have a data member which is the error of the data in the array (assuming they all have the same error), however this isn't something I want users to access if it's not numeric.

Share this post


Link to post
Share on other sites
If there's really that much difference in the internal representations, you probably shouldn't try to shoehorn it all into one templated class.

Share this post


Link to post
Share on other sites
Quote:
Original post by Alexistran
Okay that's fine for the functions but what about data members? I have a data member which is the error of the data in the array (assuming they all have the same error), however this isn't something I want users to access if it's not numeric.


I have some problems to understand this statement.

You can also use template metaprogramming magic to look for the member, but that's not really needed: if your template is using a particular class member, feeding it with a class that do not have this member will result in a compilation error.

Regards,

Share this post


Link to post
Share on other sites

This topic is 4019 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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