boost::optional<std::string> 和 char[] 的隐式构造函数

Posted

技术标签:

【中文标题】boost::optional<std::string> 和 char[] 的隐式构造函数【英文标题】:boost::optional<std::string> and implicit constructor from char[] 【发布时间】:2012-07-27 02:15:17 【问题描述】:

我已经习惯了通过让编译器弄清楚所涉及的魔法来以以下方式初始化 std::strings

std::string my_string = "hello";

以下将不起作用,因为这两种类型之间没有显式转换:

boost::optional<std::string> my_optional_string = "hello";

但这确实有效:

boost::optional<std::string> my_optional_string = std::string("hello");

现在,是否没有办法将隐式调用的单参数构造函数菊花链化以允许第二种形式?我问的原因(虽然我不想用细节来打扰你)是有一大堆类需要填充可选成员。必须显式键入所有内容似乎是一种负担(我不太担心自己,但我正在开发一个开源 API,并希望为我的用户提供尽可能多的舒适感)。任何建议表示赞赏。


编辑:对不起,我是新手,应该提供更清晰的代码示例。我有一些类(不是自己建模,只是在 C++ 中实现),其中包含要填充的可选成员,如下所示:

Class Class1 
public:
    Class1(const boost::optional<std::string>& arg_1, /*... ,*/ const boost::optional<std::string>& arg_n );
;

我希望我的 API 用户能够指定的是:

Class1 my_class("hello","there",NULL,"***");
/* ( Note: NULL is actually risky here, as some classes might also have members of type boost::optional<int> ) */

而不是:

Class1 my_class(std::string("hello"),/*or*/boost::optional<std::string>("there"),boost::optional<std::string>(),std::string("***"));

再次感谢。

【问题讨论】:

【参考方案1】:

既然构造函数被标记为explicit,为什么不显式调用构造函数呢? boost::optional&lt;std::string&gt; my_optional_string("hello");

编辑后

Xeo 已经提供了解决方案,也许你也可以为你的构造函数使用默认参数:

Class1(boost::optional<std::string> = boost::optional<std::string>(), /*...*/)
Class1(std::string arg1, /*...*/) : 
member1(arg1), /*member2(arg2), etc.*/

那么你们都可以这样Class1

Class1 my_class;
Class1 my_class("hello", "there"); // Rest of arguments use boost::optional

但是,如果您必须提供许多构造函数和可能性,也许上述方法可能不是一个好的解决方案,您可以考虑将其模板化以减少您必须编写的代码量。

【讨论】:

嗨,杰西,非常感谢您的回答。但抱歉,我应该在我的示例中说明我需要在我的类的构造函数中传递这些,请参阅更新后的问题。 感谢您的建议,但是,参数的顺序是固定的,可选的不必是最后一个。【参考方案2】:

最简单的解决方案:提供多个构造函数,一个取char const* 或更好的std::string,一个取boost::optional

如果您希望每个参数本身都有这种可能性,那么最好只模板化 ctor。

template<class A1, class A2, class A3 /*, ..., class AN*/>
Class1(A1 const& a1, A2 const& a2, A3 const& a3 /*, ... , AN const& aN*/)
  : _member1(a1)
  , _member2(a2)
  , _member3(a3)
/*, ...
  , _memberN(aN)*/
 /* ... */ 

顺便说一句,您不应该将NULL 传递给未使用的optional,而应传递boost::none

【讨论】:

感谢您向我指出 boost::none,我知道必须有更好的方法。我想我会研究具有附加构造函数的 optional<:string> 的模板特化。

以上是关于boost::optional<std::string> 和 char[] 的隐式构造函数的主要内容,如果未能解决你的问题,请参考以下文章

在 C++11 中实现 boost::optional

从非常量到常量模板参数的隐式转换在 boost::optional 中不起作用

boost::optional 返回一个布尔值并不总是有效

如何将构造函数参数转发给 boost::optional

pybind11 - 如果访问了结构的任何成员,则 boost::optional 结构的 std::vector 成员将被清空

std::optional 实现为 union vs char[]/aligned_storage