我有一个经常用于枚举包装的类,但这需要一个cpp文件。谁能告诉我如何使用constexpr
头文件如下:
// Extend-able in the future
class CDUVariable {
public:
enum Value {
baud, firmware, type, serial
};
static const CDUVariable Baud, Firmware, Type, Serial;
/// Comparison operator (used for strict weak ordering).
bool operator<(const CDUVariable& rhs) const {
return mValue < rhs.mValue;
}
/// Integral operator cast for switch statements (cast to named enum).
operator const Value() const {
return mValue;
}
/// Serialized version of the enum.
std::string getStringVal() const {
return mStringVal;
}
static const std::set<CDUVariable>& getValues() {
static std::set<CDUVariable> gValues;
if (gValues.empty()) {
gValues.insert(Baud);
gValues.insert(Firmware);
gValues.insert(Type);
gValues.insert(Serial);
}
return gValues;
}
static CDUVariable valueOf(const std::string& rStringVal) {
for (const auto& next : getValues()) {
if (next.getStringVal() == rStringVal) {
return next;
}
}
throw std::invalid_argument(
"Illegal Argument: " + rStringVal);
}
private:
CDUVariable(const Value& rValue, const std::string& rStringVal)
: mValue(rValue)
, mStringVal(rStringVal)
{}
Value mValue;
std::string mStringVal;
};
并且cpp文件是:
const CDUVariable CDUVariable::Baud(baud, "0");
const CDUVariable CDUVariable::Firmware(firmware, "1");
const CDUVariable CDUVariable::Type(type, "2");
const CDUVariable CDUVariable::Serial(serial, "3");
我想知道是否可以使用新的constexpr语法来初始化头文件中的所有内容。我的语法有问题。
我尝试按如下方式修改标题:
// Extend-able in the future
class CDUVariable {
public:
constexpr enum Value {
baud, firmware, type, serial
};
constexpr static CDUVariable Baud(baud, "0") Firmware(firmware, "1"), Type(type, "2"), Serial(serial, "3");
但这最终给了我一堆错误。我想知道如何迁移到新的constexpr语法,而这方面的优点是我可以发送一个包含这些枚举类型类的头文件库。
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(107): error C2061: syntax error: identifier 'baud'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(107): error C3646: 'Firmware': unknown override specifier
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(107): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(107): error C2059: syntax error: '('
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(147): error C2143: syntax error: missing ')' before ';'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(147): error C2098: unexpected token after data member 'mValue'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(147): error C2059: syntax error: ')'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(111): error C2065: 'mValue': undeclared identifier
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(111): error C2039: 'mValue': is not a member of 'CDUVariable'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(102): note: see declaration of 'CDUVariable'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(116): error C2065: 'mValue': undeclared identifier
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(126): error C3867: 'CDUVariable::Baud': non-standard syntax; use '&' to create a pointer to member
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(127): error C2065: 'Firmware': undeclared identifier
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(128): error C2065: 'Type': undeclared identifier
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(129): error C2065: 'Serial': undeclared identifier
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(146): error C2614: 'CDUVariable': illegal member initialization: 'mValue' is not a base or member
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(165): error C2350: 'CDUVariable::Baud' is not a static member
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(165): note: see declaration of 'CDUVariable::Baud'
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(165): error C2248: 'CDUVariable::CDUVariable': cannot access private member declared in class 'CDUVariable'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(143): note: see declaration of 'CDUVariable::CDUVariable'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(102): note: see declaration of 'CDUVariable'
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(166): error C2039: 'Firmware': is not a member of 'CDUVariable'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(102): note: see declaration of 'CDUVariable'
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(166): error C2065: 'firmware': undeclared identifier
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(167): error C2039: 'Type': is not a member of 'CDUVariable'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(102): note: see declaration of 'CDUVariable'
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(167): error C2065: 'type': undeclared identifier
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(168): error C2039: 'Serial': is not a member of 'CDUVariable'
2>c:\users\johnc\main\app739\include\vcdu\vcduconstants.h(102): note: see declaration of 'CDUVariable'
2>c:\users\johnc\main\app739\src\vcdu\vcduconstants.cpp(168): error C2065: 'serial': undeclared identifier
2>Generating Code...
答案 0 :(得分:2)
根据定义,枚举值是常量,毕竟,您无法在运行时添加值。这就是为什么你不允许在枚举声明之前放置constexpr
的原因,这是没有意义的,因为它不会改变enum
的任何内容:
constexpr enum Value { baud, firmware, type, serial };
^^^^^^^^^
illegal
作为旁注,您现在无法构建constexpr
CDUVariable
,因为其构造函数不是constexpr
。如果您尝试对其进行适当标记,则会失败,因为mStringVal
没有constexpr
构造函数,并且每个变量都必须初始化。
如果您只想存储单个字符,请使用char
作为基元,可以在编译时构建。
答案 1 :(得分:2)
我有一个经常用于枚举包装的类,但这需要一个cpp文件。谁能告诉我如何使用constexpr
要将示例缩小到最小值,请考虑以下类:
struct Example {
enum Value { A, B };
static constexpr Example Foo{Value::A, "bar" };
constexpr Example( Value v, std::string s): v{v}, s{s} {}
private:
Value v;
std::string s;
};
这或多或少是您上一次尝试的简化版本
几乎所有能够构建constexpr
版本的Example
所需的部分都已到位,但事实是:
static constexpr
个数据成员,但在Example
声明时Foo
是不完整的类型。
所有数据成员必须(我说)constexpr
可构建,std::string
没有constexpr
构造函数可以使用。
因此,你的尝试将会失败,对此毫无疑问。
此外,请注意,除非您使用的是C ++ 17,否则您无法使用constexpr
数据成员,或者您在.cpp
文件中单独定义它们,就像您现在所做的那样。那是因为这些成员没有在C ++ 11/14中隐式定义
这意味着您甚至无法将它们与std::set::insert
一起使用,因为它只接受引用。至少,除非您在.cpp
文件中添加定义,否则不能使用它们。
所以,回到问题:
任何人都可以告诉我如何使用constexpr
不,我们不能,也不值得。在我看来,你想要可以使用odr的数据成员,所以继续使用static
个并将定义放在专用文件中。
答案 2 :(得分:1)
您可以使用以下方法删除这些静态变量:
for (int rowNum = excelWSheet.getLastRowNum(); rowNum >= 0; rowNum--) {
final Row row = excelWSheet.getRow(rowNum);
if (row != null && row.getCell(colNum) != null) {
rowIndex = rowNum;
break;
}
}
和
static const std::set<CDUVariable>& getValues() {
static const std::set<CDUVariable> gValues = {
{ baud, "0"}, // or Baud(),
{ firmware, "1"},
{ type, "2"},
{ serial, "3"}
};
return gValues;
}
或
static const CDUVariable& Baud() { static const CDUVariable var{ baud, "0"}; return var; }