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

Template member function default argument

P: n/a
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
Share this Question
Share on Google+
6 Replies


P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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.