如何保证一组特定的字符作为 string_view 参数的输入?
How to guarantee a specific set of characters as input to a string_view parameter?
我正在设计实现,我希望从一组特定的字符中选择输入作为其字符串文字表示。
考虑以下一组 classes:
class enum BaseType {
BINARY = 2,
OCTAL = 8,
DECIMAL = 10,
HEXADECIMAL = 16
};
template<BaseType BASE = BaseType::DECIMAL> // Default Template
class Foo {
public:
const uint16_t Base{BASE};
private:
std::string digits_;
int64_t integral_value_;
int64_t decimal_value_;
size_t decimal_index_location_;
public:
Foo()
: digits_{""},
integral_value_{0},
decimal_value_{0}
decimal_index_location_{0}
{}
Foo(const std::string_view digit_sequence)
: digits_{digit_sequence},
integral_value_{0},
decimal_value_{0}
decimal_index_location{0}
{
// set values according to the respective digits
// from the decimal point if one exists
// and set the decimal index location if one exists...
}
};
我可能必须对尚未确定的其他非默认类型使用特化。不管怎样,我想将每种情况限制为以下字符集,如下所示:
BINARY
:
'0'
、'1'
、'.'
OCTAL
:
['0' - '7']
、'.'
DECIMAL
:
['0' - '9']
、'.'
HEXADECIMAL
:
['0' - '9']
、['a' - 'f']
、['A' - 'F']
、'.'
对于每种类型,这些都是可接受的输入:
BINARY
:
"010"
、".010"
、"01.0"
、"01.
”等...
OCTAL
:
"012345670"
、".012345670"
、"01.2345670"
、"1."
等...
DECIMAL
:
"01234567890"
、".01234567890"
、"01.234567890"
、"1."
等...
HEXADECIMAL
:
"0123456789abcdef0"
、".0123456789abcdef0"
、"01.23456789abcdef0"
、"1."
等...
"0123456789ABCDEF0"
、".0123456789ABCDEF0"
、"01.23456789ABCDEF0"
、"1."
等...
成为 class 构造函数的 string_view
参数的唯一有效输入字符集。
有没有一种简单、优雅、高效的方法来做到这一点?如果是这样,如何?这是否通过抛出异常、编译时或 运行 时断言来处理并不重要...我只想限制每个模板版本的可能有效字符集...
编辑
对于每种情况,即使是单个 '.'
也是有效输入。例如:
Foo a(".");
将被解释为 0
,稍后当我合并 exponent
部分时,指数将计算为 1
因此结果将是 0
而不是1
由于电源规则...
使用 <regex>
,你可以这样做:
static const std::regex binary_regex(R"([01]*\.?[01]*)");
static const std::regex octal_regex(R"([0-7]*\.?[0-7]*)");
static const std::regex decimal_regex(R"([0-9]*\.?[0-9]*)");
static const std::regex hex_regex(R"([0-9a-fA-F]*\.?[0-9a-fA-F]*)");
bool do_match(const std::string& s, const std::regex& regex)
{
// if (s.empty()) { return false; }
std::smatch base_match;
return std::regex_match(s, base_match, regex);
}
您甚至可以通过分组获取点之前和点之后的值
我正在设计实现,我希望从一组特定的字符中选择输入作为其字符串文字表示。
考虑以下一组 classes:
class enum BaseType {
BINARY = 2,
OCTAL = 8,
DECIMAL = 10,
HEXADECIMAL = 16
};
template<BaseType BASE = BaseType::DECIMAL> // Default Template
class Foo {
public:
const uint16_t Base{BASE};
private:
std::string digits_;
int64_t integral_value_;
int64_t decimal_value_;
size_t decimal_index_location_;
public:
Foo()
: digits_{""},
integral_value_{0},
decimal_value_{0}
decimal_index_location_{0}
{}
Foo(const std::string_view digit_sequence)
: digits_{digit_sequence},
integral_value_{0},
decimal_value_{0}
decimal_index_location{0}
{
// set values according to the respective digits
// from the decimal point if one exists
// and set the decimal index location if one exists...
}
};
我可能必须对尚未确定的其他非默认类型使用特化。不管怎样,我想将每种情况限制为以下字符集,如下所示:
BINARY
:'0'
、'1'
、'.'
OCTAL
:['0' - '7']
、'.'
DECIMAL
:['0' - '9']
、'.'
HEXADECIMAL
:['0' - '9']
、['a' - 'f']
、['A' - 'F']
、'.'
对于每种类型,这些都是可接受的输入:
BINARY
:"010"
、".010"
、"01.0"
、"01.
”等...
OCTAL
:"012345670"
、".012345670"
、"01.2345670"
、"1."
等...
DECIMAL
:"01234567890"
、".01234567890"
、"01.234567890"
、"1."
等...
HEXADECIMAL
:"0123456789abcdef0"
、".0123456789abcdef0"
、"01.23456789abcdef0"
、"1."
等..."0123456789ABCDEF0"
、".0123456789ABCDEF0"
、"01.23456789ABCDEF0"
、"1."
等...
成为 class 构造函数的 string_view
参数的唯一有效输入字符集。
有没有一种简单、优雅、高效的方法来做到这一点?如果是这样,如何?这是否通过抛出异常、编译时或 运行 时断言来处理并不重要...我只想限制每个模板版本的可能有效字符集...
编辑
对于每种情况,即使是单个 '.'
也是有效输入。例如:
Foo a(".");
将被解释为 0
,稍后当我合并 exponent
部分时,指数将计算为 1
因此结果将是 0
而不是1
由于电源规则...
使用 <regex>
,你可以这样做:
static const std::regex binary_regex(R"([01]*\.?[01]*)");
static const std::regex octal_regex(R"([0-7]*\.?[0-7]*)");
static const std::regex decimal_regex(R"([0-9]*\.?[0-9]*)");
static const std::regex hex_regex(R"([0-9a-fA-F]*\.?[0-9a-fA-F]*)");
bool do_match(const std::string& s, const std::regex& regex)
{
// if (s.empty()) { return false; }
std::smatch base_match;
return std::regex_match(s, base_match, regex);
}
您甚至可以通过分组获取点之前和点之后的值