C++;具有可选参数的构造函数 我是C++的新手,我正在尝试创建一个类层次结构,其中每个类代表一个模式文档中的节点,认为JSON模式。看一下例如a的表示。Astring可以有三个可选约束 最小长度 最大长度 模式
此外,C++;具有可选参数的构造函数 我是C++的新手,我正在尝试创建一个类层次结构,其中每个类代表一个模式文档中的节点,认为JSON模式。看一下例如a的表示。Astring可以有三个可选约束 最小长度 最大长度 模式,c++,class,c++14,optional-parameters,C++,Class,C++14,Optional Parameters,此外,字符串是一个类型,因此有一个基类表示一个类型,所有类型(布尔型,数字,…)都从该类型继承。现在,实现这一点的一种方法是写 struct Type { const std::string m_name; Type(const std::string& name) : m_name{name} {} virtual X Serialize() const { //... } }; struct String : Type { const int
字符串
是一个类型
,因此有一个基类表示一个类型
,所有类型(布尔型
,数字
,…
)都从该类型继承。现在,实现这一点的一种方法是写
struct Type {
const std::string m_name;
Type(const std::string& name)
: m_name{name}
{}
virtual X Serialize() const {
//...
}
};
struct String : Type {
const int m_max_len;
const int m_min_len;
const std::string m_pattern;
String(int min_len, int max_len, const std::string& pattern)
: Type("string")
, m_min_len(min_len)
, m_max_len(max_len)
, m_pattern(pattern)
{}
X Serialize() const override {
// If min_length was not set then it should be omitted from the serialized output.
}
};
此字符串
实现不会使约束成为可选的。怎么办
选项:
- 可以采用一种策略,将默认构造函数参数设置为一些“非法”值,如
(在这种情况下有效,因为长度不能为负),但在一般情况下不起作用。很可能所有可能的整数都是合法值,INT\u MIN
参数也是如此模式
- 对于可选参数的每个可能排列,您不希望有不同的构造函数。在这种情况下,有三个可选值将产生不同的构造函数。编译器也无法区分构造函数
和String(int-min\u-length)
String(int-max\u-length)
- 有可能做类似的事情
String(int*min\u length=nullptr,int*max\u length=nullptr,const std::String*nullptr)
但是您必须使用
/new
或为设置的参数提供左值delete
- 最后,每个成员都可以是
。std::unique\u ptr
字符串(std::unique\u ptr min\u value nullptr,std::unique\u ptr max\u value=nullptr,std::unique\u ptr pattern=nullptr)
但是,在创建
的实例时,最终会得到相当复杂的调用。此外,如果实现类型为s的容器,它可能有自己的可选参数,那么很快就会失控String
最后,代码必须与C++14兼容。您只需使用
std::optional
:
String(const std::optional<int> &min_len, const std::optional<int> &max_len,
const std::optional<std::string> &pattern);
Type *type = new String(5, {}, std::nullptr); // last 2 parameters are omitted.
字符串(常量标准::可选和最小长度,常量标准::可选和最大长度,
常量标准::可选和模式);
Type*Type=新字符串(5,{},std::nullptr);//省略最后2个参数。
对于C++14,您可以使用其他开放源代码库中存在的类似构造(例如,boost::optional
,folly::optional
)。您尝试过使用A吗(从C++17开始)?
我知道您提到需要使用与C++14兼容的代码,但是有一个可用的方法。如果不能使用std::optional,您可以编写自己的类,该类可以包含值,也可以不包含值。它不像很多代码。可以使其接口像std::optioal一样,或者可以使其有所不同,重要的是数据:
class OptInt {
bool set_;
int value_;
public:
OptInt() : set_(false) , value_(0) {}
OptInt(int v) : set_(true), value_(v) {}
// can add other ways how to create it
bool isSet() const {return set_;}
int get() const {if (!set_) throw 666; return value_;}
// can add other operations you want to it.
};
然后您可以使用这种默认构造的OptInt作为默认参数,因此它不会被设置,但如果调用者提供int参数,那么它就会被设置。我没有信誉点来评论@Kostas 为了与C++14兼容,您可以尝试具有可选名称空间的实验名称空间(如果它可用/在您的编译器上工作)
#包括
然后你可以用
String(std::experimental::optional<int> &min_len,.....)
min_len.value_or(-1)
String(标准::实验::可选和最小长度,…)
最小长度值或(-1)
我不确定你的问题到底是什么。在这里不使用多态性会容易得多,我认为“因为长度不能为负”--当值不能为负时,你应该使用无符号的整数,而不是普通的int
。我认为你应该为每个参数创建一个类,因此,您的调用看起来像String(MinLength::default(),MaxLength(42),String)
。你也可能会从中得到启发。为什么Type
与你的问题相关?当我跳过你的问题中涉及类型层次结构的部分时,这和我阅读全文时一样有意义。似乎这个问题应该集中在具有可选参数的类上,而不考虑多态性。我在多态性讨论中看到的一个相关细节是,您需要区分“未给定参数”和“给定参数未施加限制”(后者的一个示例是将最小长度设置为0)。你可能想在文本中提到这个细节。OP说“必须与C++14兼容”,而std::optional
是C++17。我认为通过常量引用传递std::optional
没有任何好处。用户可能不会提供类型为std::optional
的参数,并且将创建临时参数。这实际上与传递值相同。但是,您可能希望通过const引用传递字符串参数(不是围绕其副本构建的可选参数)。在这种情况下,您需要的是std::optional pattern
。用户可以传递std::nullopt
。即使未设置/提供最低版本,也会创造价值,而改进版本(st std one)则不会。@Jarod42说“我是C++新手”的人也许不应该弄乱放置新闻,因为它需要获得一点点性能。如果需要的话,可以在以后添加。我没有要求提供更好(更复杂)的实现,只是告知如果需要可以改进。(例如,OP可能有非默认可构造的类型)。这暗示了@generic_opto_guy在原始帖子中给出的答案。我想我会尝试这种方法。谢谢
String(std::experimental::optional<int> &min_len,.....)
min_len.value_or(-1)