Re: Mapping a non-const integral to a type Organization: ... 
 
Marcos Bento wrote:
I'm having a bit of a problem with the mapping a non-const integral to
a type. The code below shows my predicament:
int main()
{
    Types user_choice = typeX; // Actually, this is taken from
configuration file - so non-constant integral!
    const char *file = "input.txt";
    switch( user_choice ) {
        case typeX: {
            X input;
            ::read(input, file);
        }
I understand that the scope of the 'input' variable is only the case
block, but how can I take the variable input out of such block, based
on the value of user_choice (without changing X, Y, Z, and functions f
or read - these represent library defined types)?
I though of using template <typename T> struct Wrapper, and then use
Wrapper<X>, Wrapper<Y>, ... but I can't make it work based on the non-
constant enum value.
I think that you may want to take a look at Boost Variant.
If you want some sort of Wrapper, I'm not sure if this will work for you
or not, more of a point of departure than a solution. I think it has
some problems in that it won't be very efficient. If your X, Y, Z
classes are large this will have some serious drawbacks.
I think this may be similar to an Abstract Factory. I would be grateful
if someone can tell me the name of this pattern.
#include <iostream>
#include <string>
typedef enum { typeX, typeY, typeZ } Types;
class X {};
class Y {};
class Z {};
// we add an invalid class so we always have
// something to point to in Wrapper below
class Invalid {};
// WrapperBase and WrapperType<>, below,
// need an interface that is appropriate
// for X, Y and Z.
//
class WrapperBase {
public:
    virtual ~WrapperBase() {}
    virtual std::string name() const = 0;
    virtual WrapperBase *clone() const = 0;
};
template<typename T>
class WrapperType : public WrapperBase {
    T t_;
public:
    WrapperType() : t_() {}
    WrapperType(const T &t) : t_(t) {}
    T &t() { return t_; }
    std::string name() const;
    WrapperType *clone() const { return new WrapperType(t_); }
};
// specialize name for each of the
// classes we want to make, including
// WrapperType<Invalid>
template<>
std::string WrapperType<X>::name() const { return "X"; }
//
template<>
std::string WrapperType<Y>::name() const { return "Y"; }
//
template<>
std::string WrapperType<Z>::name() const { return "Z"; }
//
template<>
std::string WrapperType<Invalid>::name() const { return "Invalid"; }
// Wrapper is a little bit like a container class,
// but points to the WrapperType<> classes.
// It also needs an interface that is suitable
// for X, Y and Z. Although I suppose you
// could expose the pointer to WrapperBase.
class Wrapper {
    WrapperBase *p_; // might be better to use a smart pointer
    static Wrapper factory(const Types &t) {
        // here's our factory to make
        // a new Wrapper based on a value
        // of Types
        if(t == typeX) return WrapperType<X>();
        if(t == typeY) return WrapperType<Y>();
        if(t == typeZ) return WrapperType<Z>();
        return WrapperType<Invalid>();
    }
public:
    void swap(Wrapper &w) {
        std::swap(p_,w.p_);
    }
    Wrapper() : p_(new WrapperType<Invalid>() ) {}
    Wrapper(const Wrapper &w) : p_(w.p_->clone()) {}
    template<typename T>
    Wrapper(const WrapperType<T> &w) : p_(w.clone()) {}
    Wrapper(const Types t) : p_( factory(t).p_->clone() ) {}
    ~Wrapper() { delete p_; } // better to use some smart pointer
    //
    Wrapper &operator=(const Wrapper &w) {
        Wrapper temp(w);
        swap(temp);
        return *this;
    }
    std::string name() const { return p_->name(); }
};
// now we only need one f function
// instead of three
void f(const Wrapper &w) { std::cout << w.name() << std::endl; }
int main()  {
    // it should be easy enough to use
    // a Types variable as the argument
    // to w's ctor
    const Wrapper w(typeY);
    f(w);
}
LR
-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]