gpt4 book ai didi

c++ - cppcheck vs clang-tidy : explict constructor initializer_list

转载 作者:行者123 更新时间:2023-12-03 21:35:12 24 4
gpt4 key购买 nike

当我运行工具 clang-tidy-3.8 和 cppcheck-1.72 时,遵循 code :

#include <initializer_list>
#include <string>
#include <iostream>

using string_list = std::initializer_list<std::string>;

class Foo {
public:
explicit Foo(const string_list& strings) {
for (const auto& ss : strings) {
std::cout << ss << std::endl;
}
}
};

clang-tidy-3.8 输出:

$ > clang-tidy -checks='*' main.cpp -- -std=c++11

warning: initializer-list constructor should not be declared explicit [google-explicit-constructor] explicit Foo(const string_list& strings)



但是,如果我 删除 关键字显式,cppcheck-1.72 报告:

$ > cppcheck main.cpp --language=c++ --std=c++11 --enable=all

(style) Class 'Foo' has a constructor with 1 argument that is not explicit.



我读于 Google Cpp Guide :

Constructors that cannot be called with a single argument should usually omit explicit. Constructors that take a single std::initializer_list parameter should also omit explicit, in order to support copy-initialization (e.g. MyType m = {1, 2};).



哪个工具是正确的
根据 C++ 标准?

最佳答案

正如@KerrekSB 所说,这取决于您要执行的构建风格。
如果你使初始化列表构造函数explicit然后

  • 你不允许 YourType A = {a, b, c}; .
  • 但只允许 YourType A({a, b, c}); (或 YourType A{{a, b, c}}; )(我认为有些编译器接受 YourType A{a, b, c} 但我发现它不一致。)

  • 如果你不标记它 explict这两种情况都是允许的。
    有人主张永远不要使用=在(类的)构造函数中(甚至不是初始化列表参数),因此这最终是您通过标记 explicit 强制执行的样式 .
    标记的另一个重要副作用 explicit您必须考虑的是,您将无法将原始初始值设定项列表作为函数参数传递来代替构造的对象(这可能是限制性的,但可能是进一步样式考虑的一部分)。
    例如。 fun(arg1, arg2, {a, b, c})对比 fun(arg1, arg2, YourType({a, b, c})) .
    还要注意例如 std::vector::vector(std::initializer_list) (或任何其他标准容器)未标记 explicit .

    我的经验法则是我允许 =在构造函数中,当右侧可以用构造类型“忠实地”表示并且计算复杂度较低(例如,小于 O(N log N) 或 O(N^2))。
    IMO 没有多少情况可以通过初始化列表来完成。
    我遇到的唯一例子是 1) 数组或列表的一些转世(包括 std::vector )2)无序线性容器(但 IMO 不包括有序容器)。 3) 多维数组(嵌套初始化列表)。 4) 元组(尽管语言中有非同构的初始化列表)。
    (根据这条规则,我认为对 std::set 没有明确说明是错误的,因为 std::set 会在幕后重新排序)。

    我在实践中所做的是对 cppcheck 进行内联抑制的评论。警告,我觉得无论如何对于任何隐式单参数构造函数都需要注释。
        // cppcheck-suppress noExplicitConstructor ; because human-readable explanation here
    YourType(std::initializer_list<value_type> il){...}
    并运行 cppcheck带有选项 --inline-supp .
    (见 http://cppcheck.sourceforge.net/manual.pdf#page=19)

    关于c++ - cppcheck vs clang-tidy : explict constructor initializer_list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36604325/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com