将enums作为标志处理可以在C#中通过[Flags]属性很好地工作,但是在C++中执行此操作的最佳方法是什么?
例如,我想写:
enum AnimalFlags
{
HasClaws = 1,
CanFly =2,
EatsFish = 4,
Endangered = 8
};
seahawk.flags = CanFly | EatsFish | Endangered;
Run Code Online (Sandbox Code Playgroud)
但是,我收到关于int/ enum转换的编译器错误.是否有更好的表达方式而不仅仅是直接的铸造?优选地,我不想依赖来自第三方库的构造,例如boost或Qt.
编辑:如答案中所示,我可以通过声明seahawk.flags为避免编译器错误int.但是,我想有一些机制来强制执行类型安全,所以有人不能写seahawk.flags = HasMaximizeButton.
如果我有这样的枚举
enum Errors
{ErrorA=0, ErrorB, ErrorC};
Run Code Online (Sandbox Code Playgroud)
然后我想打印到控制台
Errors anError = ErrorA;
cout<<anError;/// 0 will be printed
Run Code Online (Sandbox Code Playgroud)
但我想要的是文本"ErrorA",我可以不使用if/switch吗?
你有什么解决方案?
在这里阅读了很多关于C++ C++风格的答案后,我还有一个小问题.我是否可以将C风格的铸件用于内置类型,long x=(long)y;或者它仍然被认为是坏的和危险的?
此代码以MSVC编译器(v141工具集,/ std:c ++ 17)的意外方式运行:
#include <iostream>
#include <limits>
#include <sstream>
#include <stdint.h>
int main() {
std::ostringstream ss;
enum Enum : int64_t {muchos_digitos = std::numeric_limits<int64_t>::max() - 1000};
ss << muchos_digitos;
std::cout << ss.str();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
具体来说,它打印"-1001".只有经过多次头部刮擦和启用/W4警告级别后才发现原因:
警告C4305:'参数':从'main :: Enum'截断到'int'
但为什么会这样呢?实际上,调试器确认int调用了重载而不是long long,但为什么呢?我怎样才能在通用代码中规避这一点?我投muchos_digitos来int64_t,但我收到的价值typename T.我可以弄清楚它是一个枚举,但我怎么知道它是一个强类型的枚举,我能找到它的基础类型吗?我不认为这是直接可能的......
GCC下的输出是正确的,但我需要代码才能与GCC,clang和MSVC三个一起使用.
PS首先没有为我的项目设置/ W4是一个错误.我建议大家在MSVC和-pedantic-errorsGCC/clang中使用这个级别,当你在编写代码时在编译时注意到它时,它确实可以节省你的时间和bizzare错误以及令人惊讶的行为.
我有一个我想在单元测试中使用的枚举类:
enum class MyEnumClass
{
MyEntryA,
MyEntryB
};
Run Code Online (Sandbox Code Playgroud)
我想用它如下:
MyEnumClass myEnumValue = MyEnumClass::MyEntryA;
BOOST_CHECK_EQUAL(myEnumValue, MyEnumClass::MyEntryB);
Run Code Online (Sandbox Code Playgroud)
但是我得到了这个错误,显然因为boost测试试图输出值:
include/boost/test/test_tools.hpp:326:14: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
ostr << t; // by default print the value
^
Run Code Online (Sandbox Code Playgroud)
添加丑陋的static_cast"解决"问题:
BOOST_CHECK_EQUAL(static_cast<int>(myEnumValue), static_cast<int>(MyEnumClass::MyEntryB));
Run Code Online (Sandbox Code Playgroud)
但是我想避免为每个枚举类做到这一点.我还想避免<<为每个枚举类定义流操作符.
是否有更简单的方法来使用带有boost测试的枚举类?
或者其他单元测试框架是否有更好的方法来处理枚举类?
我有以下代码(实际上更长,我只是放置引发错误的部分)
//Header class
enum class Color{
Rouge, Bleu, Vert
};
class Bike{
Color _color;
Bike (Color color): _color(color){
}
void print() const;
}
//Cpp file (assume all inclusions are done properly)
void Bike::print() const{
std::cout<<_color;
}
//Main
main(){
Color couleur (Color::Rouge);
Bike obj(couleur);
obj.print()
}
Run Code Online (Sandbox Code Playgroud)
因此,在我打印颜色 ( std::cout<<_color;) 之前,其他一切都工作正常。我是不是用enum错方法了?为什么我不能打印那种颜色?
错误代码
[Error] initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Color]'
Run Code Online (Sandbox Code Playgroud) 我想超载<< operator.这是我的代码:
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <algorithm>
#include <cmath>
#include <list>
using namespace std;
enum class Zustand{Neuwertig,Gut,Abgegriffen,Unbrauchbar};
class Exemplar{
private:
int aufl_num;
Zustand z;
bool verliehen;
public:
Exemplar(int aufl_num);
Exemplar(int aufl_num,Zustand z);
bool verfuegbar() const;
bool entleihen();
void retournieren(Zustand zust);
friend ostream& operator<<(ostream& os, const Exemplar& Ex);
};
//Constructor 1;
Exemplar::Exemplar(int aufl_num):
aufl_num{aufl_num},
z{Zustand::Neuwertig},
verliehen{false}
{
if(aufl_num >1000 || aufl_num <1) throw runtime_error("Enter correct number betwee 1 and 1000");
}
// Constructor 2; …Run Code Online (Sandbox Code Playgroud)