Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何为不同类型重用运算符重载?_C++_C++11_Operator Overloading_C++14_Enum Class - Fatal编程技术网

C++ 如何为不同类型重用运算符重载?

C++ 如何为不同类型重用运算符重载?,c++,c++11,operator-overloading,c++14,enum-class,C++,C++11,Operator Overloading,C++14,Enum Class,我有几个枚举定义如下: enum class Suit { spades = 1, hearts, diamonds, clubs, first = spades, last = clubs }; enum class Rank { six = 6, seven, eight, nine, ten, jack, queen, king, ace, first = six, last = ace }; 对于这些枚举中的每一个我都重载了一些运算符: Suit op

我有几个
枚举
定义如下:

enum class Suit {
    spades = 1, hearts, diamonds, clubs,
    first = spades, last = clubs
};

enum class Rank {
    six = 6, seven, eight, nine, ten, jack, queen, king, ace,
    first = six, last = ace
};
对于这些
枚举中的每一个
我都重载了一些运算符:

Suit operator++(Suit& r) { return r = (Suit)(static_cast<std::underlying_type_t<Suit>>(r) + 1); }
Rank operator++(Rank& r) { return r = (Rank)(static_cast<std::underlying_type_t<Rank>>(r) + 1); }
// more overloads ...
Suit操作符++(Suit&r){returnr=(Suit)(static_cast(r)+1)}
秩运算符++(秩&r){返回r=(秩)(静态_cast(r)+1);}
//更多重载。。。
请注意,对于这两种类型,运算符重载的实现是相同的如何避免这种代码重复?

我可以使用模板

template<class T>
T operator++(T& r) { return r = (T)(static_cast<std::underlying_type_t<T>>(r) + 1); }
模板
T运算符++(T&r){返回r=(T)(静态_转换(r)+1)}

但是这些重载应该只适用于我的自定义类型。

您可以使用模板版本将其限制在所需的枚举上

template <class E, std::enable_if_t<
    std::is_same_v<E, Suit> ||
    std::is_same_v<E, Rank>, bool> = true>
E& operator++(E& r, int) {
    return r = (E)(static_cast<std::underlying_type_t<E>>(r) + 1);
}
template=true>
E&operator++(E&r,int){
返回r=(E)(静态_-cast(r)+1);
}

您可以使用模板版本将其限制在所需的枚举上

template <class E, std::enable_if_t<
    std::is_same_v<E, Suit> ||
    std::is_same_v<E, Rank>, bool> = true>
E& operator++(E& r, int) {
    return r = (E)(static_cast<std::underlying_type_t<E>>(r) + 1);
}
template=true>
E&operator++(E&r,int){
返回r=(E)(静态_-cast(r)+1);
}

以下是如何以可伸缩的方式限制模板

#include <type_traits>

template <class> 
constexpr bool is_my_enum = false;       // most types are not my enums

enum class Suit {
    spades = 1, hearts, diamonds, clubs,
    first = spades, last = clubs
};
template<> 
constexpr bool is_my_enum<Suit> = true;  // this is my enum

enum class Rank {
    six = 6, seven, eight, nine, ten, jack, queen, king, ace,
    first = six, last = ace
};
template<> 
constexpr bool is_my_enum<Rank> = true;  // this one is mine too

enum class Moo { moo = 0 };              // but this one isn't



// define functions for my enums only
template<class T>
using for_my_enums = std::enable_if_t<is_my_enum<T>, T>;

template<class T> 
for_my_enums<T>                        
operator++(T& r) {return r = (T)(static_cast<std::underlying_type_t<T>>(r) + 1);}

template<class T> 
for_my_enums<T>                        
operator++(T& r, int) { 
    auto k = r; 
    r = (T)(static_cast<std::underlying_type_t<T>>(r) + 1); 
    return k;
}

// ... more functions ...


int main()
{
   Suit a = Suit::spades;
   ++a;                   // ok
   Moo b = Moo::moo;
   ++b;                   // compilation error, it's not my enum
}
#包括
模板
constexpr bool是_my_enum=false;//大多数类型不是我的枚举
枚举类套装{
黑桃=1,红桃,钻石,梅花,
第一个=黑桃,最后一个=梅花
};
模板
constexpr bool是_my_enum=true;//这是我的枚举
枚举类秩{
六=6,七,八,九,十,杰克,皇后,国王,王牌,
第一名=六名,最后一名=A
};
模板
constexpr bool是_my_enum=true;//这个也是我的
枚举类Moo{Moo=0};//但这个不是
//仅为我的枚举定义函数
模板
使用for_my_enums=std::enable_if_t;
模板
为了我的列举
运算符++(T&r){返回r=(T)(静态_转换(r)+1)}
模板
为了我的列举
运算符++(T&r,int){
自动k=r;
r=(T)(静态(r)+1);
返回k;
}
// ... 更多功能。。。
int main()
{
西装a=西装:黑桃;
++a、 //好的
Moo b=Moo::Moo;
++b、 //编译错误,它不是我的枚举
}

以下是如何以可伸缩的方式限制模板

#include <type_traits>

template <class> 
constexpr bool is_my_enum = false;       // most types are not my enums

enum class Suit {
    spades = 1, hearts, diamonds, clubs,
    first = spades, last = clubs
};
template<> 
constexpr bool is_my_enum<Suit> = true;  // this is my enum

enum class Rank {
    six = 6, seven, eight, nine, ten, jack, queen, king, ace,
    first = six, last = ace
};
template<> 
constexpr bool is_my_enum<Rank> = true;  // this one is mine too

enum class Moo { moo = 0 };              // but this one isn't



// define functions for my enums only
template<class T>
using for_my_enums = std::enable_if_t<is_my_enum<T>, T>;

template<class T> 
for_my_enums<T>                        
operator++(T& r) {return r = (T)(static_cast<std::underlying_type_t<T>>(r) + 1);}

template<class T> 
for_my_enums<T>                        
operator++(T& r, int) { 
    auto k = r; 
    r = (T)(static_cast<std::underlying_type_t<T>>(r) + 1); 
    return k;
}

// ... more functions ...


int main()
{
   Suit a = Suit::spades;
   ++a;                   // ok
   Moo b = Moo::moo;
   ++b;                   // compilation error, it's not my enum
}
#包括
模板
constexpr bool是_my_enum=false;//大多数类型不是我的枚举
枚举类套装{
黑桃=1,红桃,钻石,梅花,
第一个=黑桃,最后一个=梅花
};
模板
constexpr bool是_my_enum=true;//这是我的枚举
枚举类秩{
六=6,七,八,九,十,杰克,皇后,国王,王牌,
第一名=六名,最后一名=A
};
模板
constexpr bool是_my_enum=true;//这个也是我的
枚举类Moo{Moo=0};//但这个不是
//仅为我的枚举定义函数
模板
使用for_my_enums=std::enable_if_t;
模板
为了我的列举
运算符++(T&r){返回r=(T)(静态_转换(r)+1)}
模板
为了我的列举
运算符++(T&r,int){
自动k=r;
r=(T)(静态(r)+1);
返回k;
}
// ... 更多功能。。。
int main()
{
西装a=西装:黑桃;
++a、 //好的
Moo b=Moo::Moo;
++b、 //编译错误,它不是我的枚举
}

对于什么纸牌游戏,你需要增加一套衣服?@NeilButterworth我想在基于范围的For循环中使用它。对于什么纸牌游戏,你需要增加一套衣服?@NeilButterworth我想在基于范围的For循环中使用它。