Topic: hint for special template declaration


Author: "Richard Smith" <richard@ex-parrot.com>
Date: Tue, 23 Oct 2001 16:45:07 GMT
Raw View
"Mycroft Holmes" <holmes@technologist.REMOVEME.com> wrote in message
news:0uQA7.71049$1H1.7282365@news.infostrada.it...
> I got the idea.
> btw, which compiler do you use?
> afaik, the following is illegal:
>
> template<typename T>
> struct isPointer<T>
> {
>     static bool x;
> }
>
>
> template<typename T>
> struct isPointer<T*>
> {
>     static bool x;
> }

It is illegal.  This declares two partial specialisations of template
<class> struct isPointer, but doesn't actually declare the primary template
anywhere.  What you should do is

template<typename T>
struct isPointer       // NB: Removing the <T> here makes this the primary
template declaration.
{
    static bool x;
};

template<typename T>
struct isPointer<T*>
{
    static bool x;
};



However, if you're using MS Visual C++, this won't work.  (Microsoft doesn't
believe in partial specialisation.)

> // x is shared between ALL isPointer's, so you cannot set true/false.
> "declaration incompatible"

No.  x is shared between all isPointer<T>s for a given T, but each different
T has its own copy.

> // you have to use a static method which returns true/false.
> // (and in fact your code is not compiled! I tried several compilers under
> win32)
>
> // but this compiles:
>
> template<typename T>
> class isPointer
> {
>
>  static bool val()
>  {
>   return false;
>  }
> };

Yes, but you can't instantiate a template based on the return value of this
function, whereas you can instantiate a template on a static const member of
a class.  So, for example, the example that Anthony Williams gave you
earlier in this thread,

> > template<typename T,bool is_pointer>
> > struct f_helper
> > {
> >     static void func(T x)
> >     {
> >         // do general case
> >     }
> > };
> >
> > // is_pointer is true
> > template<typename T>
> > struct f_helper<T,true>
> > {
> >     static void func(T x)
> >     {
> >         // special case for pointers
> >     }
> > };
> >
> > template<typename T>
> > void f(T x)
> > {
> >     return f_helper<T,isPointer<T>::result>::func(x);
> > }
> >

chooses the correct f_helper using the value of isPointer<T>::result and
wouldn't work if isPointer<T>::result was a function.


--
Richard Smith


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Fri, 19 Oct 2001 10:26:30 GMT
Raw View
I'd like C++ to be able to declare SETS of templates.
a set of templates is a template specialization which is the same for a
family of types.
some sets might be
1) all atomic types
2) all pointer types
3) all objects whose size satisfies a valid c++ boolean expression


for example

template < sizeof(T1)==8 || sizeof(T1)==16 >
void func( T1 x )


would overload/specialize func for all objects of size == 8 or 16.

--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Fri, 19 Oct 2001 15:10:03 GMT
Raw View
"Mycroft Holmes" <holmes@technologist.REMOVEME.com> wrote in message
news:X1Tz7.50049$1H1.6064022@news.infostrada.it...
> I'd like C++ to be able to declare SETS of templates.
> a set of templates is a template specialization which is the same for a
> family of types.
> some sets might be
> 1) all atomic types
> 2) all pointer types
> 3) all objects whose size satisfies a valid c++ boolean expression
>
>
> for example
>
> template < sizeof(T1)==8 || sizeof(T1)==16 >
> void func( T1 x )
>
>
> would overload/specialize func for all objects of size == 8 or 16.

You already can do this:

template<typename T>
struct isPointer
{
    static const bool result=false; // most types are not pointers
};

// set flag for pointers
template<typename T>
struct isPointer<T*>
{
    static const bool result=true;
};

template<typename T,bool is_pointer>
struct f_helper
{
    static void func(T x)
    {
        // do general case
    }
};

// is_pointer is true
template<typename T>
struct f_helper<T,true>
{
    static void func(T x)
    {
        // special case for pointers
    }
};

template<typename T>
void f(T x)
{
    return f_helper<T,isPointer<T>::result>::func(x);
}

and likewise for other conditions, such as your sizeof() condition

template<typename T>
struct sizeIs8or16
{
    static const bool result=(sizeof(T)==8 || sizeof(T==16));
};

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Mycroft Holmes" <holmes@technologist.REMOVEME.com>
Date: Mon, 22 Oct 2001 11:36:25 GMT
Raw View
I got the idea.
btw, which compiler do you use?
afaik, the following is illegal:

template<typename T>
struct isPointer<T>
{
    static bool x;
}


template<typename T>
struct isPointer<T*>
{
    static bool x;
}

// x is shared between ALL isPointer's, so you cannot set true/false.
"declaration incompatible"
// you have to use a static method which returns true/false.
// (and in fact your code is not compiled! I tried several compilers under
win32)

// but this compiles:

template<typename T>
class isPointer
{

 static bool val()
 {
  return false;
 }
};


template<typename T>
class isPointer<T*>
{
 static bool val()
 {
  return true;
 }

};

....

--
 The set of solutions is never empty.
 Two solutions together form a new problem.
-- Mycroft Holmes

> You already can do this:
>
> template<typename T>
> struct isPointer
> {
>     static const bool result=false; // most types are not pointers
> };
>
> // set flag for pointers
> template<typename T>
> struct isPointer<T*>
> {
>     static const bool result=true;
> };
>
> template<typename T,bool is_pointer>
> struct f_helper
> {
>     static void func(T x)
>     {
>         // do general case
>     }
> };
>
> // is_pointer is true
> template<typename T>
> struct f_helper<T,true>
> {
>     static void func(T x)
>     {
>         // special case for pointers
>     }
> };
>
> template<typename T>
> void f(T x)
> {
>     return f_helper<T,isPointer<T>::result>::func(x);
> }
>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Mon, 22 Oct 2001 15:44:22 GMT
Raw View
"Mycroft Holmes" <holmes@technologist.REMOVEME.com> wrote in message
news:0uQA7.71049$1H1.7282365@news.infostrada.it...
> I got the idea.
> btw, which compiler do you use?
> afaik, the following is illegal:
>
> template<typename T>
> struct isPointer<T>
> {
>     static bool x;
> }
>
>
> template<typename T>
> struct isPointer<T*>
> {
>     static bool x;
> }

This is fine. isPointer<int>::x and isPointer<double>::x and
isPointer<int*>::x are all distinct variables.

> // x is shared between ALL isPointer's, so you cannot set true/false.
> "declaration incompatible"

static const  variables of integral type can be assigned values in the class
definition.

9.4.2p4 says:

"If a static data member is of const integral or const enumeration type, its
declaration in the class definition can specify a constant-initializer which
shall be an integral constant expression (5.19). In that case, the member
can appear in integral constant expressions within its scope. The member
shall still be defined in a namespace scope if it is used in the program and
the namespace scope definition shall not contain an initializer."

> // you have to use a static method which returns true/false.
> // (and in fact your code is not compiled! I tried several compilers under
> win32)

These compilers are therefore all not standard compliant. gcc 3.01 accepts
the code OK, as does Comeau C++.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 22 Oct 2001 19:34:49 GMT
Raw View
Mycroft Holmes wrote:
>
> I got the idea.
> btw, which compiler do you use?
> afaik, the following is illegal:
>
> template<typename T>
> struct isPointer<T>
> {
>     static bool x;
> }
>
> template<typename T>
> struct isPointer<T*>
> {
>     static bool x;
> }
>
> // x is shared between ALL isPointer's, so you cannot set true/false.
> "declaration incompatible"

For a fixed type T, all isPointer<T> objects share the same x. However,
isPointer<T>::x is a different object for each type T.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]