Boost logo

Boost Users :

Subject: Re: [Boost-users] Using different variables based on template type
From: Ryan McConnehey (mccorywork_at_[hidden])
Date: 2009-06-02 02:51:23


Scott McMurray wrote:
2009/6/1 Ryan McConnehey <mccorywork@gmail.com>:
  
I have a couple of functions that provide the same functionality for
different types.  I'd like to combine them to reduce code duplication.  An
example of two functions is listed below.

std::map<std::string, uint16>   m_Uint16;
std::map<std::string, uint32>   m_Uint32;

void putUint16(std::string const& variableName, uint16 const& value) {
  m_Uint16[variableName] = value;
}

void putUint32(std::string const& variableName, uint32 const& value) {
  m_Uint32[variableName] = value;
}

The functions can't be combined into a template since they are the interface
for the programmer.  Is there a boost library that would let me call a
template or common function that would use a different variable based on the
variable type?

    

If you need those function names, I think you're stuck with a macro,
since a template can't generate an identifier based on an argument.

    #define NASTY_PREFIX_HERE_PUT_FOR_TYPE(T) \
    void put_##T(std::string const& variableName, T const& value) { \
        m_##T[variableName] = value; \
    } \
    std::map<std::string, T> m_##T

    NASTY_PREFIX_HERE_PUT_FOR_TYPE(uint16);
    NASTY_PREFIX_HERE_PUT_FOR_TYPE(uint32);

If you can change the API, then you could use a template like this:

template <typename T>
class foo { // can't think of a good name
    std::map<std::string, T> m;
  public:
    void put(std::string const& variableName, T const& value) {
        m[variableName] = value;
    }
};

Then publically inherit from foo<uint16> and foo<uint32> (I think
there's an inherit_linearly or something that would help, given a
typelist, though it might have hiding problems).  If you dislike
overload resolution, I think you can do something like this:

   whatever.foo<uint16>::put("yay", 0x1234);

Not certain about the syntax there, though.  Or add a template
function to do the dispatch to the correct base, allowing syntax like:

    whatever.put<uint16>("boo", 0x4321);

Since you likely need a matching get, for which overload resolution is
less nice, the last version is probably my favourite.

Good luck,
~ Scott
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Where would you rank this solution?

std::map<std::string, uint16>   m_Uint16;
std::map<std::string, uint32>   m_Uint32;

template <typename T>
void put(std::map<std::string, T> const& map, std::string const& variableName, T const& value) {
  map[variableName] = value;
}

void putUint16(std::string const& variableName, uint16 const& value) {
  put(m_Uint16, variableName, value);
}

void putUint32(std::string const& variableName, uint32 const& value) {
  put(m_Uint32, variableName, value);
}

Ryan

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net