By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,200 Members | 1,559 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,200 IT Pros & Developers. It's quick & easy.

default template parameters

P: n/a
Dear all,

I have a question about default template parameters.

I want to have a second template parameter which as a default parameter,
but depends on the first one (see below). Is something like that possible?
Some workaround?

Thank you,
Patrick
// Definitions
template <typename T1=int,typename T2=int> class foo;
// this is not working (sure):
template <double, typename T2=double> class foo;

// Implementation
template <typename T1,typename T2> class foo{};

int main()
{
foo<> a1; // foo class <int,int>
foo<int> a2; // foo class <int,int>
foo<float> a3; // foo class <float,int>
foo<float,float> c; // foo class <float,float>

// BUT this should be defined via second definition:
foo<double> b; // foo class <double,double>

return 0;
}
Jul 19 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
On Wed, 17 Sep 2003 11:29:47 +0200
"Patrick Kowalzick" <Pa***************@cern.ch> wrote:
// Definitions
template <typename T1=int,typename T2=int> class foo;


tryed something like:
template <typename T1=int,typename T2=T1> class foo;
???

i don't know if it works ... !!
Jul 19 '05 #2

P: n/a
Hi Clemens,
// Definitions
template <typename T1=int,typename T2=int> class foo;


tryed something like:
template <typename T1=int,typename T2=T1> class foo;
???

i don't know if it works ... !!


No, it is not working. Please regard a3 with one float. This would be
<float,float> as well.

foo<int> a2; // foo class <int,int>
foo<float> a3; // foo class <float,int>
foo<double> b; // foo class <double,double>

Thank you,
Patrick
Jul 19 '05 #3

P: n/a
On Wed, 17 Sep 2003 11:29:47 +0200, "Patrick Kowalzick"
<Pa***************@cern.ch> wrote:
Dear all,

I have a question about default template parameters.

I want to have a second template parameter which as a default parameter,
but depends on the first one (see below). Is something like that possible?
Default parameters are decided solely by the primary template -
specializations can't have defaults.
Some workaround?

Thank you,
Patrick

//Declaration (and definition)
template <typename T1=int,typename T2=T1> class foo{};

//Declaration and definition of partial specialization
//for T1=double.
template <typename T1> class foo<double, T1>{};

int main()
{
foo<> a1; // foo class <int,int>
foo<int> a2; // foo class <int,int>
foo<float> a3; // foo class <float,int>


This will give foo<float, float>. If that isn't what you want (and you
want foo<float, int>), you'll have to say why, and why double should
be different.

Tom
Jul 19 '05 #4

P: n/a
Dear Tom,

thanks for your help. I tried to strip the problem as much as I can and you
find the result below.

The aim is to get a function foo() which has different return types when
called with different template parameters. Sure you will say, this could be
critical from a semantic point of view, but in this case it is not, as the
return types have same meanings and behaviour (anyway they have to be
different, e.g bounded_vector<double,3> and bounded_vector<double,2> as
fixed size vectors which is close to my real problem).

Normally class_A and class_B are templated classes as well, what makes it
neccessary to use a partial specialized class to get a kind of "partial
specialized function". This is an explanation for the "huge" overhead below.

Anyway, I have a possibility with one return type which works fine (like in
the comment part below as a default template argument), but the other would
be nicer :-).

Regards,
Patrick

P.S.: Is this an answer to the question why, or not? LOL

#include <iostream>

class class_A {};
class class_B {};

struct return_A
{
static void print() { std::cout << "Return Type return_A" << std::endl; }
};
struct return_B
{
static void print() { std::cout << "Return Type return_B" << std::endl; }
};
template < typename T , typename r_type > class foo_class;

template < typename r_type > class foo_class < class_A , r_type >
{
public:
typedef r_type return_type;
static return_type foo() {
std::cout << "Specialization < class_A >, ";
return_type::print();
return return_type();
}
};

template < typename r_type > class foo_class < class_B , r_type >
{
public:
typedef r_type return_type;
static return_type foo() {
std::cout << "Specialization < class_B >, ";
return_type::print();
return return_type();
}
};


template < typename T , typename return_type>
return_type foo()
{
return foo_class< T , return_type>::foo();
}

int main()
{

// These calls work quite fine, but I want to have an easier interface
foo< class_A , return_A > ();
foo< class_A , return_B > ();

foo< class_B , return_A > ();
foo< class_B , return_B > ();

// Simpilfied calls
// foo< class_A > (); // shall result in foo< class_A , return_A > ();
as default
// foo< class_B > (); // shall result in foo< class_B , return_B > ();
as default

// changing
// template < typename T , typename r_type > class foo_class;
// to
// template < typename T , typename r_type = return_A> class foo_class;
// does not help at all :-(

return 0;
}
Jul 19 '05 #5

P: n/a
On 18 Sep 2003 04:14:43 -0700, ko*******@gmx.de (Patrick Kowalzick)
wrote:
Dear Tom,

thanks for your help. I tried to strip the problem as much as I can and you
find the result below.

The aim is to get a function foo() which has different return types when
called with different template parameters. Sure you will say, this could be
critical from a semantic point of view, but in this case it is not, as the
return types have same meanings and behaviour (anyway they have to be
different, e.g bounded_vector<double,3> and bounded_vector<double,2> as
fixed size vectors which is close to my real problem).

Normally class_A and class_B are templated classes as well, what makes it
neccessary to use a partial specialized class to get a kind of "partial
specialized function". This is an explanation for the "huge" overhead below.
Ok, I think. It might be clearer if you used the real class names
below.
Anyway, I have a possibility with one return type which works fine (like in
the comment part below as a default template argument), but the other would
be nicer :-).

Regards,
Patrick

P.S.: Is this an answer to the question why, or not? LOL
Just about, I think.

#include <iostream>

class class_A {};
class class_B {};

struct return_A
{
static void print() { std::cout << "Return Type return_A" << std::endl; }
};
struct return_B
{
static void print() { std::cout << "Return Type return_B" << std::endl; }
};
You've got nothing tying class_A to its default return, return_A. One
possibility is:

class class_A
{
public:
typedef return_A default_return_type;
};

template < typename T , typename r_type > class foo_class;

template < typename r_type > class foo_class < class_A , r_type >
{
public:
typedef r_type return_type;
static return_type foo() {
std::cout << "Specialization < class_A >, ";
return_type::print();
return return_type();
}
};

template < typename r_type > class foo_class < class_B , r_type >
{
public:
typedef r_type return_type;
static return_type foo() {
std::cout << "Specialization < class_B >, ";
return_type::print();
return return_type();
}
};

template < typename T , typename return_type>
return_type foo()
{
return foo_class< T , return_type>::foo();
}

int main()
{

// These calls work quite fine, but I want to have an easier interface
foo< class_A , return_A > ();
foo< class_A , return_B > ();

foo< class_B , return_A > ();
foo< class_B , return_B > ();

// Simpilfied calls
// foo< class_A > (); // shall result in foo< class_A , return_A > ();
as default
// foo< class_B > (); // shall result in foo< class_B , return_B > ();
as default

// changing
// template < typename T , typename r_type > class foo_class;
// to
// template < typename T , typename r_type = return_A> class foo_class;
// does not help at all :-(

return 0;
}


Ok, you want the syntax

foo<class_A>();

Since you can't have default template arguments for functions, you
need an overload of foo. You also need to tie class_A to return_A in
some way. If you can put the typedef suggested above into class_A,
then this works:

template <class T>
typename T::default_return_type foo()
{
return foo_class<T, typename T::default_return_type>::foo();
}

If you can't modify class_A, class_B, etc., you might add the
information to your specializations of foo_class. e.g.

template<typename T>
class foo_class;

template<>
class foo_class<class_A>
{
public:
typedef return_A default_return_type;
template <class return_type>
static return_type foo() {
std::cout << "Specialization<class_A>, ";
return_type::print();
return return_type();
}
};

template<>
class foo_class<class_B>
{
public:
typedef return_B default_return_type;
template <class return_type>
static return_type foo() {
std::cout << "Specialization<class_B>, ";
return_type::print();
return return_type();
}
};

template<typename T, typename return_type>
return_type foo()
{
return foo_class<T>::template foo<return_type>();
}

template<typename T>
typename foo_class<T>::default_return_type foo()
{
return foo_class<T>::template
foo<typename foo_class<T>::default_return_type>();
}
If you need to leave foo_class as it is, the final possibility is to
add separate traits binding a class to its default return:

template<class T>
struct foo_defaut_return;

template<>
struct foo_defaut_return<class_A>
{
typedef return_A type;
};

template<>
struct foo_defaut_return<class_B>
{
typedef return_B type;
};

And now foo looks like this:

template<typename T, typename return_type>
return_type foo()
{
return foo_class<T, return_type>::foo();
}

template<typename T>
typename foo_defaut_return<T>::type foo()
{
return foo_class<T, typename foo_defaut_return<T>::type>::foo();
}

Or similar. Anyway, I hope that gives you some ideas.

Tom
Jul 19 '05 #6

P: n/a
Dear Tom,

I will try your proposals and hope to get it running.

Anyway your explanations solved two other problems I had ;-)

Thanks a lot.
Patrick
Jul 19 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.