coincoin coincoin - 3 months ago 11
C++ Question

Generic symmetric pair c++ for double and single types

I am trying to have a template structure which can handle symmetric pairs. The comparisons operators are implemented to make the struct work in std::map.

So far I am using the following code :

template<typename T, typename U>
struct SymmetricPair
{
SymmetricPair() : m_id(std::pair<T,U>()) {}
SymmetricPair(const SymmetricPair<T,U>& id) : m_id(id) {}
SymmetricPair(const SymmetricPair<U,T>& id) : SymmetricPair(id.m_id) {}
SymmetricPair(const std::pair<T,U>& id) : m_id(id) {}
SymmetricPair(const std::pair<U,T>& id) : m_id(std::pair<T,U>(id.second,id.first)) {}
SymmetricPair(const T id_t, const U id_u) : m_id(std::pair<T,U>(id_t, id_u)) {}
SymmetricPair(const U id_u, const T id_t) : m_id(std::pair<T,U>(id_t, id_u)) {

bool operator< (const SymmetricPair<T,U>& rhs) const { return m_id < rhs.m_id; }
bool operator!=(const SymmetricPair<T,U>& rhs) const { return m_id != rhs.m_id; }
bool operator==(const SymmetricPair<T,U>& rhs) const { return m_id == rhs.m_id; }
bool operator< (const SymmetricPair<U,T>& rhs) const { return m_id < SymmetricPair<T,U>(rhs.m_id).m_id; }
bool operator!=(const SymmetricPair<U,T>& rhs) const { return m_id != SymmetricPair<T,U>(rhs.m_id).m_id; }
bool operator==(const SymmetricPair<U,T>& rhs) const { return m_id == SymmetricPair<T,U>(rhs.m_id).m_id; }

std::pair<T,U> m_id;
};


Using
SymmetricPair<std::string,int> pair(std::pair<int,std::string>(42,"bde"));
for example works fine.

However, I have troubles (compile time errors) when template arguments
T
and
U
are the same e.g.
SymmetricPair<std::string,std::string>
since some operations are considered already defined

'SymmetricPair<T,U>::SymmetricPair(const SymmetricPair<T,U> &)' : member function already defined or declared
'SymmetricPair<T,U>::SymmetricPair(const std::pair<_Ty1,_Ty2> &)' : member function already defined or declared
'SymmetricPair<T,U>::SymmetricPair(const T,const U)' : member function already defined or declared
'bool SymmetricPair<T,U>::operator <(const SymmetricPair<T,U> &) const' : member function already defined or declared
'bool SymmetricPair<T,U>::operator !=(const SymmetricPair<T,U> &) const' : member function already defined or declared
'bool SymmetricPair<T,U>::operator ==(const SymmetricPair<T,U> &) const' : member function already defined or declared


How can I fix that ? I am using VC++ 2005 (so no C++11).

If there is a also a way to make the structure more elegant, I am interested.

Answer

I believe the easiest way is partial specialization, especially if C++11 is not available:

template<typename T>
struct SymmetricPair<T, T>
{
    SymmetricPair() : m_id() {}
    SymmetricPair(const SymmetricPair& id) : m_id(id.m_id) {}
    SymmetricPair(const std::pair<T,T>& id) : m_id(id) {}
    SymmetricPair(const T id_t, const T id_u) : m_id(id_t, id_u) {}

    bool operator< (const SymmetricPair<T,T>& rhs) const { return m_id <  rhs.m_id; }
    bool operator!=(const SymmetricPair<T,T>& rhs) const { return m_id != rhs.m_id; }
    bool operator==(const SymmetricPair<T,T>& rhs) const { return m_id == rhs.m_id; }

    std::pair<T,T> m_id;
};
Comments