472,119 Members | 1,527 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,119 software developers and data experts.

Template member function default argument

What is the correct syntax for default values to member function
templates?
Here is my example:
1 struct A
2 {
3 typedef int typeA;
4 };
5
6 struct B
7 {
8 template<class Y>
9 void f(typename Y::typeA = typename Y::typeA()) {}
10 };
11
12 int main()
13 {
14 B t;
15 t.f<A>(4);
16 return 0;
17 }

Sun Workshop 6.2 compiler complains about line 9 with the following
message: Operand expected instead of "typename".

G++ 3.1.1 handles it without any problem.
Any help would greatly appreciated.
Jul 22 '05 #1
6 2515
Mike Alexeev wrote in news:85**************************@posting.google.c om
in comp.lang.c++:
What is the correct syntax for default values to member function
templates?
Here is my example:
1 struct A
2 {
3 typedef int typeA;
4 };
5
6 struct B
7 {
typedef typename Y::typeA typeA;
8 template<class Y>
9 void f(typename Y::typeA = typename Y::typeA()) {}
void f(typeA = typeA()) {}

10 };
11
12 int main()
13 {
14 B t;
15 t.f<A>(4);
16 return 0;
17 }

Sun Workshop 6.2 compiler complains about line 9 with the following
message: Operand expected instead of "typename".

G++ 3.1.1 handles it without any problem.
Any help would greatly appreciated.


IIUC the second typename isn't required as typename Y::typeA()
*isn't* a declaration. OTOH I couldn't find a compiler that
rejects it either.

If removing the typename doesn't work with g++ 3.1.1 then use
the above (inline) workaround.

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #2
Rob Williscroft <rt*@freenet.co.uk> wrote in message news:<Xn**********************************@130.133 .1.4>...
Mike Alexeev wrote in news:85**************************@posting.google.c om
in comp.lang.c++:
What is the correct syntax for default values to member function
templates?
Here is my example:
1 struct A
2 {
3 typedef int typeA;
4 };
5
6 struct B
7 {


typedef typename Y::typeA typeA;
8 template<class Y>
9 void f(typename Y::typeA = typename Y::typeA()) {}


void f(typeA = typeA()) {}

10 };
11
12 int main()
13 {
14 B t;
15 t.f<A>(4);
16 return 0;
17 }

Sun Workshop 6.2 compiler complains about line 9 with the following
message: Operand expected instead of "typename".

G++ 3.1.1 handles it without any problem.
Any help would greatly appreciated.


IIUC the second typename isn't required as typename Y::typeA()
*isn't* a declaration. OTOH I couldn't find a compiler that
rejects it either.

If removing the typename doesn't work with g++ 3.1.1 then use
the above (inline) workaround.

HTH.

Rob.


Rob,
Unfortunately your solution won't work because it is a member function
template and you can not do typedef outside the template. This was my
original problem.
template<class Y>
void f(typename Y::typeA = typename Y::typeA()) {}

Mike
Jul 22 '05 #3
Mike Alexeev wrote in news:85**************************@posting.google.c om
in comp.lang.c++:
IIUC the second typename isn't required as typename Y::typeA()
*isn't* a declaration. OTOH I couldn't find a compiler that
rejects it either.

If removing the typename doesn't work with g++ 3.1.1 then use
the above (inline) workaround.

HTH.

Rob.
Rob,
Unfortunately your solution won't work because it is a member function


Sorry I missed that, but my solution was to remove the second typename
which should still work, have you tried it ? does g++ 3.1.1 require the
typename ?, neither of g++ 3.2.2 or g++ 3.4 do.
template and you can not do typedef outside the template. This was my
original problem.
template<class Y>
void f(typename Y::typeA = typename Y::typeA()) {}


If you still need a workaround:

template < typename T >
struct default_arg
{
static value() { return T(); }
};
struct B
{
template < typename Y >
void f(
typename Y::typeA arg = default_arg< typename Y::typeA >::value()
)
{
}
};

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #4
mi*************@qwest.com (Mike Alexeev) wrote in message
Here is my example:
1 struct A
2 {
3 typedef int typeA;
4 };
5
6 struct B
7 {
8 template<class Y>
9 void f(typename Y::typeA = typename Y::typeA()) {}
The above looks fine, but I've seen some compilers get confused with
code like this. Try the fix mentioned below for line 15, and if that
doesn't work, then consider this: The compiler does not do template
argument deduction for nested types, so why not move the template
<class Y> from B::f to B? But if you really need it you can write a
second function that forwards to the first.

8 template<class Y>
9 void f(typename Y::typeA) {}
10 template<class Y>
11 void f() { typedef typename Y::typeA typeA; return
f(typeA()); }

Also, when my compiler Borland C++ 6 wouldn't accept code like what
you have, I turned f into a functor-like class, so it allowed me to
typedef typename Y::typeA typeA as if it were a member of the class,
so that in operator() I could say operator()(typeA = typeA()). This
is much like Rob's approach.

10 };
11
12 int main()
13 {
14 B t;
15 t.f<A>(4);
It should be

t.template f<A>(4);

G++ 3.1 accepts either version, but it should accept only the latter.
16 return 0;
17 }

Jul 22 '05 #5
Rob Williscroft <rt*@freenet.co.uk> wrote in message news:<Xn**********************************@130.133 .1.4>...
Mike Alexeev wrote in news:85**************************@posting.google.c om
in comp.lang.c++:
IIUC the second typename isn't required as typename Y::typeA()
*isn't* a declaration. OTOH I couldn't find a compiler that
rejects it either.

If removing the typename doesn't work with g++ 3.1.1 then use
the above (inline) workaround.

HTH.

Rob.


Rob,
Unfortunately your solution won't work because it is a member function


Sorry I missed that, but my solution was to remove the second typename
which should still work, have you tried it ? does g++ 3.1.1 require the
typename ?, neither of g++ 3.2.2 or g++ 3.4 do.
template and you can not do typedef outside the template. This was my
original problem.
template<class Y>
void f(typename Y::typeA = typename Y::typeA()) {}


If you still need a workaround:

template < typename T >
struct default_arg
{
static value() { return T(); }
};
struct B
{
template < typename Y >
void f(
typename Y::typeA arg = default_arg< typename Y::typeA >::value()
)
{
}
};

Rob.


Rob,
Thanks for the workaround. It works perfectly.
As far as second typename goes G++ 3.1.1 handles it without any
problem. I am going to try it with the 3.4 version as well. It was the
problem with Sun Workshop 6.2 compiler (CC) which I was not able to
compile both with second typename or without it.
Mike
Jul 22 '05 #6
Siemel Naran wrote in news:3d**************************@posting.google.c om
in comp.lang.c++:
11
12 int main()
13 {
14 B t;
15 t.f<A>(4);


It should be

t.template f<A>(4);

G++ 3.1 accepts either version, but it should accept only the latter.
16 return 0;


Nope it should accept the former, 't' *isn't* a dependant
name it's a 'B', so its member 'f' isn't a dependant name.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Valeriu Catina | last post: by
2 posts views Thread by CoolPint | last post: by
5 posts views Thread by krishnaroskin | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.