字符串VS词法中的构造函数从字符串转换?

时间:2013-05-27 07:51:17

标签: c++ boost constructor

我刚刚意识到我的代码库有点不连贯,一些对象是使用构造函数A(const std::string&)从字符串构造的,而另一些是使用boost::lexical_cast<A>(const std::string&)从字符串构造的。

根据我的理解,这些需要满足相同的需求,但在许多方面表现不同,格式错误的字符串和转换的异常是我脑海中浮现的第一个,但我确信还有其他含义。所以我的问题是:我应该使用什么以及为什么?


编辑:根据@ hetepeperfan的评论,我正在改变const std :: string&amp;中的std :: string参数,这就是我在第一时间的意思

2 个答案:

答案 0 :(得分:2)

我可以想象一个类InputFile(类似于std::ifstream),它接受表示文件系统中文件路径的字符串:

InputFile f("/dir/file.txt");
use(f);

在这里使用boost::lexical_cast至少会很奇怪。

我猜这个观察结果可以这样推广:如果您的类型A表示与std::string“兼容”或可转换为std::string的值,则您有两种选择。但是如果你在接口中公开一个构造函数,它接受一个类型std::string的非可选参数用于转换值之外的其他目的,那么只使用构造函数是有意义的(并且这个构造函数应该是explicit )。

答案 1 :(得分:1)

  

根据我的理解,这些满足了[...]

的需要

他们不满足同样的需要。用于创建对象的接口应始终表达创建对象背后的语义。词法强制转换是对对象实例的字符串值的强制转换(重新解释)。如果您的对象是使用字符串值构造但不是来自字符串中的值,则使用boost :: lexical_cast只会令人困惑。

  

[...]但是在许多方面表现不一样,格式错误的字符串和转换的例外是我脑海中浮现的第一个,但我确信还有其他含义。所以我的问题是:我应该使用什么以及为什么?

如果你的对象可以用任何字符串值构造(即不依赖于字符串中的值而只是在内部复制字符串),那么你应该将它直接传递给构造函数。 / p>

如果将字符串值传递给构造函数意味着您可以创建一个具有无效值的实例,则应该使用工厂函数(在实例化对象之前抛出错误)或[不太喜欢]在构造函数中添加异常验证(不太理想,不太干净,在大多数情况下设计更差)。

如果您的对象实例建模了一个值/类型特化,可以通过解释字符串中的值(“强制转换”)来创建,那么您应该支持通过boost::lexical_cast<YourClass>(const std::string&)创建它。

编辑:如果您构造一个具有名称的对象(例如某个记录器对象),但记录器的功能/值不依赖于名称(对象记录相同的名称) ,只是使用不同的名称),那么你不应该定义一个基于lexical_cast的实现(因为名称不会改变记录器的功能)。

如果您创建一个对象,其值/功能取决于字符串中的值(解析字符串中的值并将其转换为“复数”类实例),那么实例的行为取决于什么在字符串中(lexical_cast<ComplexNo>("(0 + 0i)")将返回一些不能被分割的东西,而不是lexical_cast<ComplexNo>("(1 + 0i)"))。在这种情况下(值对象取决于字符串中的内容),应该支持lexical_cast。

基本上,为值对象提供基于lexical_cast的实现。