Non-type function template parameters

M

mmomike

Why can't I do this:

enum
{
MY_INT, MY_DOUBLE
};

template<typename T, int N>
void foo(T xx)
{
struct
{
int type;
int size;
T data;
} bundle;

bundle.type = N;
bundle.size = sizeof(T);
bundle.data = xx;

// record_bundle((void*) &bundle);
}


template void foo<int, MY_INT>(int);
template void foo<double, MY_DOUBLE>(double);

main()
{
int i = 0;
double d = 3.14159;

foo(i);
foo(d);
}
 
I

Ian Collins

Jeff said:
Because foo takes two compile-time parameters, but the compiler can only
deduce one of them from context here.

enum
{
MY_INT, MY_DOUBLE
};

template<class T> struct my;
template<> struct my<int> { enum { value = MY_INT }; };
template<> struct my<double> { enum { value = MY_DOUBLE }; };
Bugger, I was just about to post the same code!
 
N

Noah Roberts

Jeff said:
Because foo takes two compile-time parameters, but the compiler can only
deduce one of them from context here.

enum
{
MY_INT, MY_DOUBLE
};

template<class T> struct my;
template<> struct my<int> { enum { value = MY_INT }; };
template<> struct my<double> { enum { value = MY_DOUBLE }; };

template<typename T>
void foo(T xx)

Alternatively you could keep a similar signature as before by using the
above metafunction and this definition:

template < typename T, int N = my<T>::value >
void foo(T xx)

This would of course allow the client to override the normal selection
of N should that be desirable and safe.
 
N

Noah Roberts

Jeff said:
Function templates can't have default arguments (under the current
standard). You would have to pass the arguments to a class template
that could, in turn, have a default argument.

Yeah, forgot. Would have to be:

template < typename T, int N = my<T>::value >
struct foo_impl
{
static void apply(T xx)
{
...
}
};
template < typename T >
void foo(T t) { return foo_impl<T>::apply(t); }

I've always hated that rule.

Yet another alternative though would be:

template < typename T >
void foo(T xx, int N = my<T>::value)
{
}

That IS legal and would provide additional benefit of not implementing
several instances of the function for the same type when provided
different N values....if that's appropriate/safe.

Yet another alternative:

template < typename T, int N >
void foo(T xx)...

template < typename T >
void foo(T xx)
{
foo<T,my<T>::value>(xx);
}
....
foo(5);

Which does what it would be nice if the compiler did. If you invert the
T and N arguments you could use the top foo as: foo<5>(19.7).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top