Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > optional parameter in a template

Reply
Thread Tools

optional parameter in a template

 
 
Vladimir Jovic
Guest
Posts: n/a
 
      07-19-2010
Hello,

Next example :

// code
class A
{
public :
typedef int type1;
};
class B
{
public :
typedef int type1;
typedef int type2;
};

template < typename T >
class MyClass
{
typedef typename T::type1 type1;
typedef typename T::type2 type2;
};

int main()
{
MyClass< B > c1;
MyClass< A > c2;
}
// !code

should give next errors when compiled :
g++ s.cpp
s.cpp: In instantiation of ‘MyClass<A>’:
s.cpp:26: instantiated from here
s.cpp:20: error: no type named ‘type2’ in ‘class A’



In my real code, class MyClass is my class, and I can change it, but I
can not change classes A and B. There are more classes with different
number of typedefs, but they all have the same pattern (similar to above) :
class D
{
public :
typedef int type1;
typedef int type2;
typedef int type3;
typedef int type4;
};

Is there a way to typedef type2 in the class MyClass as void, if it not
defined in the template parameter?
Is there a way to make the above example compile?

Thank in advance
 
Reply With Quote
 
 
 
 
Helge Kruse
Guest
Posts: n/a
 
      07-19-2010

"Vladimir Jovic" <(E-Mail Removed)> wrote in message
news:i219lc$lg1$(E-Mail Removed)...
> Hello,
>
> Next example :
>
> // code
> class A
> {
> public :
> typedef int type1;
> };
> class B
> {
> public :
> typedef int type1;
> typedef int type2;
> };
>
> template < typename T >
> class MyClass
> {
> typedef typename T::type1 type1;
> typedef typename T::type2 type2;
> };
>
> int main()
> {
> MyClass< B > c1;
> MyClass< A > c2;
> }
> // !code
>

....
>
> Is there a way to typedef type2 in the class MyClass as void, if it not
> defined in the template parameter?


Add the class myA and use it instead of class A.


class myA : public A
{
public:
typedef void type2;
};

int main()
{
MyClass< B > c1;
MyClass< myA > c2;
}


Helge




 
Reply With Quote
 
 
 
 
Alf P. Steinbach /Usenet
Guest
Posts: n/a
 
      07-19-2010
* Vladimir Jovic, on 19.07.2010 12:33:
>
> Next example :
>
> // code
> class A
> {
> public :
> typedef int type1;
> };
> class B
> {
> public :
> typedef int type1;
> typedef int type2;
> };
>
> template < typename T >
> class MyClass
> {
> typedef typename T::type1 type1;
> typedef typename T::type2 type2;
> };
>
> int main()
> {
> MyClass< B > c1;
> MyClass< A > c2;
> }
> // !code
>
> should give next errors when compiled :
> g++ s.cpp
> s.cpp: In instantiation of ‘MyClass<A>’:
> s.cpp:26: instantiated from here
> s.cpp:20: error: no type named ‘type2’ in ‘class A’
>
>
>
> In my real code, class MyClass is my class, and I can change it, but I
> can not change classes A and B. There are more classes with different
> number of typedefs, but they all have the same pattern (similar to above) :
> class D
> {
> public :
> typedef int type1;
> typedef int type2;
> typedef int type3;
> typedef int type4;
> };
>
> Is there a way to typedef type2 in the class MyClass as void, if it not
> defined in the template parameter?


Yes.


> Is there a way to make the above example compile?


Helge Kruse's reply else-thread, deriving from the classes, may be the most
practical.

But if it's impractical to derive, e.g. lots of constructors, then e.g. a bit of
SFINAE (Substitution Failure Is Not An Error for template argument),


<code>
#include <iostream>
#include <typeinfo>

class A
{
public :
typedef int type1;
};
class B
{
public :
typedef int type1;
typedef int type2;
};

namespace detail{
typedef char YesType;
typedef struct { char x[2]; } NoType;

template< class U, int >
struct Type1
{
typedef void T;
};

template< class U >
struct Type1< U, sizeof( YesType ) >
{
typedef typename U::type1 T;
};

template< class U, int >
struct Type2
{
typedef void T;
};

template< class U >
struct Type2< U, sizeof( YesType ) >
{
typedef typename U::type2 T;
};

template< class T >
class TypesOf
{
private:
template< class U >
static YesType hasType1( typename U::type1 const* );

template< class U >
static NoType hasType1( ... );

template< class U >
static YesType hasType2( typename U::type2 const* );

template< class U >
static NoType hasType2( ... );

public:
typedef typename Type1< T, sizeof( hasType1<T>( 0 ) ) >::T T1;
typedef typename Type2< T, sizeof( hasType2<T>( 0 ) ) >::T T2;
};

} // namespace detail

template < typename T >
class MyClass
{
public:
typedef typename detail::TypesOf< T >::T1 type1;
typedef typename detail::TypesOf< T >::T2 type2;
};

int main()
{
MyClass< B > c1;
MyClass< A > c2;

std::cout << typeid( MyClass< A >::type1 ).name() << std::endl;
std::cout << typeid( MyClass< A >::type2 ).name() << std::endl;
}
</code>


Cheers & hth.,

- Alf (intricate kludge creation mood)

--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
Vladimir Jovic
Guest
Posts: n/a
 
      07-19-2010
Alf P. Steinbach /Usenet wrote:
> * Vladimir Jovic, on 19.07.2010 12:33:


>
>> Is there a way to make the above example compile?

>
> Helge Kruse's reply else-thread, deriving from the classes, may be the
> most practical.
>
> But if it's impractical to derive, e.g. lots of constructors, then e.g.
> a bit of SFINAE (Substitution Failure Is Not An Error for template
> argument),
>
>
> <code>
> #include <iostream>
> #include <typeinfo>
>
> class A
> {
> public :
> typedef int type1;
> };
> class B
> {
> public :
> typedef int type1;
> typedef int type2;
> };
>
> namespace detail{
> typedef char YesType;
> typedef struct { char x[2]; } NoType;
>
> template< class U, int >
> struct Type1
> {
> typedef void T;
> };
>
> template< class U >
> struct Type1< U, sizeof( YesType ) >
> {
> typedef typename U::type1 T;
> };
>
> template< class U, int >
> struct Type2
> {
> typedef void T;
> };
>
> template< class U >
> struct Type2< U, sizeof( YesType ) >
> {
> typedef typename U::type2 T;
> };
>
> template< class T >
> class TypesOf
> {
> private:
> template< class U >
> static YesType hasType1( typename U::type1 const* );
>
> template< class U >
> static NoType hasType1( ... );
>
> template< class U >
> static YesType hasType2( typename U::type2 const* );
>
> template< class U >
> static NoType hasType2( ... );
>
> public:
> typedef typename Type1< T, sizeof( hasType1<T>( 0 ) ) >::T T1;
> typedef typename Type2< T, sizeof( hasType2<T>( 0 ) ) >::T T2;
> };
>
> } // namespace detail
>
> template < typename T >
> class MyClass
> {
> public:
> typedef typename detail::TypesOf< T >::T1 type1;
> typedef typename detail::TypesOf< T >::T2 type2;
> };
>
> int main()
> {
> MyClass< B > c1;
> MyClass< A > c2;
>
> std::cout << typeid( MyClass< A >::type1 ).name() << std::endl;
> std::cout << typeid( MyClass< A >::type2 ).name() << std::endl;
> }
> </code>



Although the Helge's solution is nice, this is actually what I was
looking for.

Thank you
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Defining a method with an optional parameter Ahmed Moustafa Java 6 04-17-2012 12:34 PM
Using declaration inside first template parameter as default valuefor second template parameter. Stuart Redmann C++ 5 12-14-2007 08:42 AM
Bug in python!? persistent value of an optional parameter in function! C Barr Leigh Python 12 03-08-2007 08:12 AM
Optional Parameter Requirements dhable@gmail.com Python 2 10-30-2006 10:05 AM
How to make a "long&" parameter optional Otto Wyss C++ 6 11-09-2004 07:32 PM



Advertisments