用于双和单类型的泛型对称对c++
Generic symmetric pair c++ for double and single types
我试图有一个模板结构,可以处理对称对。实现比较操作符是为了使结构体在std::map中工作。
到目前为止,我使用以下代码: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;
};
例如使用SymmetricPair<std::string,int> pair(std::pair<int,std::string>(42,"bde"));
就可以。
然而,当模板参数T
和U
相同时,我有麻烦(编译时错误),例如SymmetricPair<std::string,std::string>
,因为一些操作被认为已经定义
'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
我怎样才能解决这个问题?我使用vc++ 2005(所以没有c++ 11)。
如果还有一种方法可以使结构更优雅,我很感兴趣。
我认为最简单的方法是部分专门化,特别是在c++ 11不可用的情况下:
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;
};
我宁愿扩展pair,或者在特定情况下使用不同的相等操作符和哈希操作符。
我刚刚写了这个类:
/** Copyright (C) 2016 Ultimaker - Released under terms of the AGPLv3 License */
#ifndef UTILS_SYMMETRIC_PAIR
#define UTILS_SYMMETRIC_PAIR
#include <utility> // pair
namespace cura
{
/*!
* A utility class for a pair of which the order between the first and the second doesn't matter.
*
* tparam A The type of both elements of the pair.
*/
template<class A>
class SymmetricPair : public std::pair<A, A>
{
public:
/*!
* Forwarding std::pair constructor
*/
template<class U>
SymmetricPair(const SymmetricPair<U>& pr)
: std::pair<A, A>(pr)
{
}
/*!
* Forwarding std::pair constructor
*/
template<class U>
SymmetricPair(SymmetricPair<U>&& pr)
: std::pair<A, A>(pr)
{
}
/*!
* Forwarding std::pair constructor
*/
SymmetricPair(const A& first, const A& second)
: std::pair<A, A>(first, second)
{
}
/*!
* Forwarding std::pair constructor
*/
template<class U>
SymmetricPair(U&& first, U&& second)
: std::pair<A, A>(first, second)
{
}
/*!
* Forwarding std::pair constructor
*/
template <class... Args1, class... Args2>
SymmetricPair(std::piecewise_construct_t pwc, std::tuple<Args1...> first_args, std::tuple<Args2...> second_args)
: std::pair<A, A>(pwc, first_args, second_args)
{
}
/*!
* Equality operator which checks if two SymmetricPairs are equal regardless of the order between first and second
*/
bool operator==(const SymmetricPair& other) const
{
return (std::pair<A, A>::first == other.first && std::pair<A, A>::second == other.second) || (std::pair<A, A>::first == other.second && std::pair<A, A>::second == other.first);
}
};
}//namespace cura
namespace std
{
/*!
* Hash operator which creates a hash regardless of the order between first and second
*/
template<class A>
struct hash<cura::SymmetricPair<A>>
{
size_t operator()(const cura::SymmetricPair<A>& pr) const
{ // has to be symmetric wrt a and b!
return std::hash<A>()(pr.first) + std::hash<A>()(pr.second);
}
};
}//namespace std
#endif // UTILS_SYMMETRIC_PAIR
在其他情况下,我简单地定义了一个单独的等式和哈希函数,并使用它们,例如在unordered_map<Key, Value, MyHasher, MyEquality>
中。
相关文章:
- 错误处理.将系统错误代码映射到泛型
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 链表的泛型函数remove()与成员函数remove)
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何编写将要继承的泛型代码?
- C++17 如何保存泛型可调用对象以供以后使用
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- C++泛型类错误,问题出在哪里?
- C++泛型类,单独实现?
- 将参数传递给泛型 lambda 时复制构造函数不正确
- 泛型枚举和其他类型的重载模板函数
- 使用泛型类型推送到堆栈时出现问题
- 可变参数泛型 lambda 和函数重载
- C++ 泛型和多态性:这种模式可行吗?
- 这些语句是否等效(静态变量、常量变量和泛型)
- Java 是否像C++模板一样具有泛型推论?
- 为堆栈实现泛型集合
- 以特征类型作为参数的泛型函数回调
- 用于双和单类型的泛型对称对c++