Problems with 'template specialization' and/or 'value to type mapping'

Problems with 'template specialization' and/or 'value to type mapping'

Post by Geurt Vo » Sat, 17 Feb 2001 01:15:35



Consider the following class:

template <typename T, T value>
struct C {};

I need to distinguish between 'value == 0' and 'value != 0', which
should be handled at compile time, so I either need a specialized
version for 'value == 0', or require value-to-type mapping. Is there
any way to do this?

The following code doens't seem valid:

template <typename T>
struct C<T,0> {};

at least my compiler tells it isn't (Borland C++ 5.4: Partial
specializations
may not specialize dependent non-type parameters), and I assume it's
right (didn't check the standard, because that won't change my compiler).

I spend several hours last night finding a solution, and every time I came
close, the compiler (also GCC) would *on it. The one thing I can
detect with value to type mapping is when (in the example) 'value == 0',
but not when 'value != 0'.

One thing: a theoretical solution won't be good enough. That is, I actually
have use for it :). Specialization within template classes is not supported,
which I think could do the trick with something like:

template <typename T> struct Map {
    template <T> struct Value {
          typedef long Type;
     };
     template <> struct Value<0> {
          typedef short Type;
     };

Quote:};

and then implement some function for 'long' and 'short', but alas, the
compiler doesn't like it...

[real-life example:

template <class Implementor, class PropertyTraits, class CallbackPolicy,
          typename CallbackPolicy::template CallPolicy<Implementor,
                                        PropertyTraits>::GetMethodPtr
getMethod,
          typename CallbackPolicy::template CallPolicy<Implementor,
                                        PropertyTraits>::SetMethodPtr
setMethod>
class Property {};

I need to detect when getMethod and/or setMethod are 0.
]

TIA,
Geurt


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

Problems with 'template specialization' and/or 'value to type mapping'

Post by Howard Hinna » Sat, 17 Feb 2001 09:43:29




| Consider the following class:
|
| template <typename T, T value>
| struct C {};
|
| I need to distinguish between 'value == 0' and 'value != 0', which
| should be handled at compile time, so I either need a specialized
| version for 'value == 0', or require value-to-type mapping. Is there
| any way to do this?
|
| The following code doens't seem valid:
|
| template <typename T>
| struct C<T,0> {};

How 'bout:

template <typename T, T value, bool not_zero>
struct Cimp   // value != 0
{
   Cimp() {}

Quote:};

template <typename T, T value>
struct Cimp<T, value, true>  // value == 0
{
   Cimp() {}

Quote:};

template <typename T, T value>
struct C
   : Cimp<T, value, value == 0>
{
   C() {}

Quote:};

-Howard


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

Problems with 'template specialization' and/or 'value to type mapping'

Post by Geurt Vo » Sun, 18 Feb 2001 01:43:31


Quote:> template <typename T, T value>
> struct C {};

> I need to distinguish between 'value == 0' and 'value != 0', which
> should be handled at compile time, so I either need a specialized
> version for 'value == 0', or require value-to-type mapping. Is there
> any way to do this?

I actually found a solution last night. Here goes:

template <typename T, T value> struct Dep {

Quote:};

template <typename X, typename Y> struct Spec {
    typedef short Type;

Quote:};

template <typename X>
struct Spec<X,Dep<X,0> > {
    typedef long Type;

Quote:};

template <typename T, T value>
struct C {
    void G() { F(Spec<T,Dep<T,value> >::Type()); }

    void F(short) { cout << "value == 0" << endl; }
    void F(long) { cout << "value != 0" << endl; }

Quote:};

int main()
{
    C<int,100> c100;
    c100.G(); // calls F(short);
    C<int,0> c0;
    c0.G(); // calls F(long);

Quote:}

The one problem I ran into: for some reason it doesn't work
for member function pointers (can't set it to 0). For Borland
I could get around it by simply introducing a dumb indirection:

template <typename T> struct Ind {
    typedef T IT;

Quote:};

template <typename T, T::IT value>
struct Dep {

Quote:};

Which makes the following declaration for Spec:

    Spec<Ind<T>,Dep<Ind<T>,value> >::Type

Geurt


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

Problems with 'template specialization' and/or 'value to type mapping'

Post by Geurt Vo » Sun, 18 Feb 2001 04:40:26


Quote:> How 'bout:

> template <typename T, T value, bool not_zero>
> struct Cimp   // value != 0
> {
>    Cimp() {}
> };

> template <typename T, T value>
> struct Cimp<T, value, true>  // value == 0
> {
>    Cimp() {}
> };

> template <typename T, T value>
> struct C
>    : Cimp<T, value, value == 0>
> {
>    C() {}
> };

No good, same problem as without the bool. Partial
specializations may not specialize dependent non-type
parameters, so the specialization for Cimp isn't valid.

Geurt


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

Problems with 'template specialization' and/or 'value to type mapping'

Post by Howard Hinna » Mon, 19 Feb 2001 08:45:53




| > How 'bout:
| >
| > template <typename T, T value, bool not_zero>
| > struct Cimp   // value != 0
| > {
| >    Cimp() {}
| > };
| >
| > template <typename T, T value>
| > struct Cimp<T, value, true>  // value == 0
| > {
| >    Cimp() {}
| > };
| >
| > template <typename T, T value>
| > struct C
| >    : Cimp<T, value, value == 0>
| > {
| >    C() {}
| > };
| >
|
| No good, same problem as without the bool. Partial
| specializations may not specialize dependent non-type
| parameters, so the specialization for Cimp isn't valid.

I disagree.  14.5.4/8 says:

| A non-type argument is non-specialized if it is the name of a non-type
| parameter. All other non-type arguments are specialized.

Thus "value" in the Cimp partial specialization is _not_ specialized, and
thus not subject to 14.5.4/9:

| The type of a template parameter corresponding to a specialized non-type
| argument shall not be dependent on a parameter of the specialization.

But perhaps I am misinterpreting these paragraphs (wouldn't be the first
time).

-Howard


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

Problems with 'template specialization' and/or 'value to type mapping'

Post by Ross Smit » Mon, 19 Feb 2001 08:53:53



> Consider the following class:

> template <typename T, T value>
> struct C {};

> I need to distinguish between 'value == 0' and 'value != 0', which
> should be handled at compile time, so I either need a specialized
> version for 'value == 0', or require value-to-type mapping. Is there
> any way to do this?

I haven't got Borland installed to try this on, but it works with GCC:

#include <iostream>

template <typename T, T value> struct C_generic {
  void hello() const { std::cout << "Generic hello\n"; }

Quote:};

template <typename T> struct C_zero {
  void hello() const { std::cout << "Specialised hello\n"; }

Quote:};

template <bool Flag, typename T, typename F> struct If;
template <typename T, typename F> struct If<true, T, F> {
  typedef T Type;
Quote:};

template <typename T, typename F> struct If<false, T, F> {
  typedef F Type;

Quote:};

template <typename T, T value> struct C:
  public If<value == 0, C_zero<T>, C_generic<T, value> >::Type {};

int main() {
  C<int, 0>().hello();
  C<int, 1>().hello();
  return 0;

Quote:}

--

========================================================================
          "Normally he was insane, but he had lucid moments
          when he was merely stupid."     -- Heinrich Heine


      [ about comp.lang.c++.moderated. First time posters: do this! ]

 
 
 

1. Converting '->' to '.' using a template...

Hello,

I seem to have vague recollection of encountering a template that
allowed me to instantiate an object in C++ in the following manner..

MyClass *obj = new MyClass();

...wrapping it up in a template...

TheTemplate<MyClass> tobj(obj);

...although maybe (as I cannot remember), perhaps the following was
used instead (assuming I have no previous instance of MyClass)...

TheTemplate<MyClass> tobj;

Now, let's say obj has a method called doSomething(), one can do...

obj->doSomething();

...but with the template, it was possible to do...

tobj.doSomething();

...the template did not have to have any of the methods of MyClass
defined in it and it was not much more than 7 to 10 lines of code. The
main purpose of this template was to allow you use the '.' when
calling methods, but the underlying object did not get automatically
destroyed when its parent function/object/etc. went out of scope. I
think it might have been called Ref (but this could just be a
proprietary name). Does anyone know of such a template?

Cheers,

Matthew

2. Matlab for Linux

3. Positions of the qualifiers 'typename' and 'template'

4. Location of Printing to Windows mini-HOWTO

5. NT Server/2000 Pro slow directory

6. Specializations of 'real(T),imag(T),abs(),norm(T)' for arithmetic types

7. Help: Writing article about Embedded systems testing

8. ListView problem capturing 'INS' and 'DEL' keys

9. 'initializing' : truncation from 'const double' to 'float' warning

10. Problem with 'new' and 'delete'

11. Problem: 'function1' hides virtual function 'function2'

12. {'a','b','\0'} not equivalent to "ab"??