5

我已经习惯于通过让编译器找出所涉及的魔法来以下列方式初始化 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,"stackoverflow");
/* ( 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("stackoverflow"));

再次感谢。

4

2 回答 2

7

既然构造函数被标记了explicit,为什么不显式调用构造函数呢?boost::optional<std::string> 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

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

于 2012-07-27T03:07:23.063 回答
1

最简单的解决方案:提供多个构造函数,一个 takechar const*或 better std::string,一个taking 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.

于 2012-07-29T10:30:36.703 回答