Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #7696

Re: Templated Casting operators

From Kai-Uwe Bux <jkherciueh@gmx.net>
Newsgroups comp.lang.c++
Subject Re: Templated Casting operators
Followup-To comp.lang.c++
Date 2011-07-10 12:03 +0200
Organization University of Bielefeld
Message-ID <ivbtdi$rd2$1@hoshi.visyn.net> (permalink)
References (6 earlier) <f966f5b5-a173-45f5-b1ea-035ca5977502@n5g2000yqh.googlegroups.com> <iv9ed1$67q$1@hoshi.visyn.net> <b781d567-f97a-4951-b3fb-b6702884a8d8@h12g2000vbx.googlegroups.com> <ivanek$g9k$1@hoshi.visyn.net> <129c15d7-bb88-4a2c-a42e-c9292e491a8a@w4g2000yqm.googlegroups.com>

Followups directed to: comp.lang.c++

Show all headers | View raw


Narinder wrote:

[...]
> In my case the functions foo_ref, foo_cref, foo_val will be given (by
> the client) and may ( and most probably will)  be compiled without any
> knowledge of the types reference and const_reference. So I would need
> it to work with :
> 
> --------------------------
> void foo_ref ( double & ) {
>   std::cout << "reference\n";
> }
> 
> void foo_cref ( const double & ) {
>   std::cout << "const reference\n";
> }
> 
> void foo_val ( double  ) {
>   std::cout << "value\n";
> }
> --------------------------

Ok, if cannot fiddle with the signatures, I think you can still avoid 
explicitly mentioning types in client code:

#include <iostream>

struct oops {};

template < typename T >
class const_reference {

  T const * ptr;
  
public:

  const_reference ( T const & r )
    : ptr ( &r )
  {}
  
  T const & get ( void ) {
    return ( *ptr );
  }

  operator T const & ( void ) {
    return ( *ptr );
  }
  
};

template < typename T >
class reference {

  T * ptr;
  
public:

  reference ( T & r )
    : ptr ( &r )
  {}
  
  T & get ( void ) {
    return ( *ptr );
  }

  operator T & ( void ) {
    return ( *ptr );
  }
  
};

template < typename T >
class wrapper {
private:

  T *       the_ptr;
  T const * the_c_ptr;
  
public:
  
  wrapper ( T & ref )
    : the_ptr ( &ref )
    , the_c_ptr ()
  {}

  wrapper ( T const & cref )
    : the_ptr ()
    , the_c_ptr ( &cref )
  {}
  
  operator reference<T> ( void ) {
    std::cout << "convert to non-const reference\n";
    if ( the_ptr ) {
      return ( *the_ptr );
    }
    throw ( oops() );
  }

  operator const_reference<T> ( void ) {
    std::cout << "convert to const reference\n";
    if ( the_ptr ) {
      return ( *the_ptr );
    }
    return ( *the_c_ptr );
  }

  operator T ( void ) {
    std::cout << "convert to value\n";
    if ( the_ptr ) {
      return ( *the_ptr );
    }
    return ( *the_c_ptr );
  }
  
};


template < typename T >
struct call_helper_ref {

  void (&f) ( T & );
  
  call_helper_ref ( void (&fct) ( T & ) )
    : f ( fct )
  {}

  void operator() ( reference<T> arg ) const {
    f( arg );
  }

};

template < typename T >
struct call_helper_cref {

  void (&f) ( T const & );
  
  call_helper_cref ( void (&fct) ( T const & ) )
    : f ( fct )
  {}

  void operator() ( const_reference<T> arg ) const {
    f( arg );
  }

};

template < typename T >
struct call_helper_value {

  void (&f) ( T );
  
  call_helper_value ( void (&fct) ( T ) )
    : f ( fct )
  {}

  void operator() ( T arg ) const {
    f( arg );
  }

};

template < typename T >
call_helper_ref< T > call ( void (&f) ( T & ) ) {
  return ( call_helper_ref<T>(f) );
}

template < typename T >
call_helper_cref< T > call ( void (&f) ( T const & ) ) {
  return ( call_helper_cref<T>(f) );
}

template < typename T >
call_helper_value< T > call ( void (&f) ( T ) ) {
  return ( call_helper_value<T>(f) );
}



// client code
// ===========

double const pi = 3.14159;
double e = 2.71828;

typedef wrapper< double > klass;


void foo_ref ( double & ) {
  std::cout << "reference\n";
}

void foo_cref ( double const & ) {
  std::cout << "const reference\n";
}

void foo_val ( double ) {
  std::cout << "value\n";
}


int main ( void ) {
  klass rw ( e );
  klass ro ( pi );
  call(foo_val)( rw );
  call(foo_cref)( rw );
  call(foo_ref)( rw );
  call(foo_val)( ro );
  call(foo_cref)( ro );
  call(foo_ref)( ro );
}



> (In fact to be even more precise, in my real scenario they will be
> class constructors.)
[...]

Now, that is more tricky as "constructors don't have names". I have to 
ponder whether template magic can detect whether a class has a constructor 
by value, reference, or const-reference.


Best,

Kai-Uwe Bux

Back to comp.lang.c++ | Previous | Next — Previous in thread | Find similar | Unroll thread


Thread

Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-07 16:34 -0700
  Re: Templated Casting operators Alexander Bartolich <alexander.bartolich@gmx.at> - 2011-07-08 00:58 +0000
    Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-07 22:36 -0700
      Re: Templated Casting operators Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-07-08 09:42 +0200
        Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-08 01:16 -0700
          Re: Templated Casting operators Ian Collins <ian-news@hotmail.com> - 2011-07-08 20:23 +1200
        Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-08 01:37 -0700
          Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-08 06:28 -0700
        Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-08 01:40 -0700
          Re: Templated Casting operators Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-07-09 00:06 +0200
            Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-09 03:16 -0700
              Re: Templated Casting operators Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-07-09 13:34 +0200
                Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-09 07:18 -0700
                Re: Templated Casting operators Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-07-10 01:15 +0200
                Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-09 21:39 -0700
                Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-09 22:01 -0700
                Re: Templated Casting operators Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-07-10 13:43 +0200
                Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-10 05:55 -0700
                Re: Templated Casting operators Narinder <narinder.claire@gmail.com> - 2011-07-10 00:19 -0700
                Re: Templated Casting operators Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-07-10 12:03 +0200

csiph-web