Boost logo

Boost Users :

Subject: Re: [Boost-users] Using different variables based on template type
From: Scott McMurray (me22.ca+boost_at_[hidden])
Date: 2009-06-02 02:33:53


2009/6/1 Ryan McConnehey <mccorywork_at_[hidden]>:
> 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 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