c++ 函子上显式转换运算符的基本原理

llew8vvj  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(82)

当我短暂休息时,我的工作场所切换到使用静态代码分析器。他们在我正在工作的项目上运行它,分析器标记的一个特定问题如下所示(简化示例):

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

编辑

似乎有些人无法阅读我提供的示例代码(漂亮的教科书内容),仍然建议其他算法/习惯用法,完全没有看到实际问题是关于函子上的转换运算符,其唯一目的是计算和返回算法的结果。
如果问题是关于如何改进加法算法,那么标题应该这么说。
所以我决定在这个编辑中隐藏任何实现细节,以便这些人更容易。
对不起,下面的一些评论现在不再有任何意义,但记录卡住了,所以我不得不移动针一点,以推动事情向前发展(希望)。

ni65a41a

ni65a41a1#

我会完全取消任何转换运算符。

int result = std::for_each(...).get();

字符串
其中get()与您当前的operator int执行相同的操作。
你知道for_each的结果不是一个整数,它是你的函数对象。为什么,为什么你要避免显式地从函数到值的转换?无论如何,这是一个值得怀疑的想法。当然,你仍然可以这样做,但是你想要干净的无警告代码,对吗?好吧,在我的书中,干净,无警告的代码不应该自动将函数转换为整数。我同意static_cast几乎同样丑陋,这就是为什么我建议使用命名函数

相关问题