当我短暂休息时,我的工作场所切换到使用静态代码分析器。他们在我正在工作的项目上运行它,分析器标记的一个特定问题如下所示(简化示例):
struct calcSomething
{
int result;
calcSomething() : result(0) {}
void operator()(const int v) { /*does something*/ }
operator int() const { return result; }
};
void foo()
{
std::vector<int> myvector(10);
// exercise for reader: stick some values in `myvector`
int result = std::for_each(myvector.begin(), myvector.end(), calcSomething());
}
字符串
分析器标记以下问题:
warning: CodeChecker: 'operator int' must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
operator int() const { return result; }
型
建议对functor的修复如下:
struct calcSomething
{
...
explicit operator int() const { return result; }
};
型
但是如果我按照建议修复了我的functor,静态分析器很快就会标记出以下问题:
warning: CodeChecker: no viable conversion from '(anonymous namespace)::calcSomething' to 'int' [clang-diagnostic-error]
型
我现在需要添加显式类型转换:
void foo()
{
...
int total = static_cast<int>(std::for_each(myvector.begin(), myvector.end(), calcSomething()));
}
型
上面的例子仅仅是一个简化的真实的问题,否则只会添加填料,没有实质内容。
我在教科书和编程参考网页上看到过很多类似的函子例子,但我从来没有认为这些函子是不安全的,也从来没有见过有人把它们标记为不安全的。
那么代码分析器有什么意义吗?或者它让我的函子的转换运算符显式化,结果让我添加静态类型转换,这有点过分了?
从美学的Angular 来看,我觉得一个简单的问题,一个优雅的解决方案,现在积累了很多丑陋的语法填充。但也许这是我们为编写安全(r)代码付出的代价。
旁注:TIL explicit
不仅适用于ctors
编辑
似乎有些人无法阅读我提供的示例代码(漂亮的教科书内容),仍然建议其他算法/习惯用法,完全没有看到实际问题是关于函子上的转换运算符,其唯一目的是计算和返回算法的结果。
如果问题是关于如何改进加法算法,那么标题应该这么说。
所以我决定在这个编辑中隐藏任何实现细节,以便这些人更容易。
对不起,下面的一些评论现在不再有任何意义,但记录卡住了,所以我不得不移动针一点,以推动事情向前发展(希望)。
1条答案
按热度按时间ni65a41a1#
我会完全取消任何转换运算符。
字符串
其中
get()
与您当前的operator int
执行相同的操作。你知道for_each的结果不是一个整数,它是你的函数对象。为什么,为什么你要避免显式地从函数到值的转换?无论如何,这是一个值得怀疑的想法。当然,你仍然可以这样做,但是你想要干净的无警告代码,对吗?好吧,在我的书中,干净,无警告的代码不应该自动将函数转换为整数。我同意
static_cast
几乎同样丑陋,这就是为什么我建议使用命名函数