【发布时间】:2016-08-04 21:34:25
【问题描述】:
当我运行工具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
警告:初始化列表构造函数不应被显式声明 [google-explicit-constructor] 显式 Foo(const string_list& 字符串)
但是,如果我删除关键字显式,cppcheck-1.72 报告:
$ > cppcheck main.cpp --language=c++ --std=c++11 --enable=all
(style) 类 'Foo' 有一个带有 1 个非显式参数的构造函数。
我在Google Cpp Guide阅读:
不能用单个参数调用的构造函数通常应该省略显式。采用单个 std::initializer_list 参数的构造函数也应该省略显式,以支持复制初始化(例如 MyType m = {1, 2};)。
哪个工具是正确的 根据 C++ 标准?
【问题讨论】:
-
“正确”是什么意思?您希望如何使用您的构造函数?
-
clang-tidy (3.8) 对
that a constructor with only 1 argument has to be explicit和that a constructor with an initializer-list should not be explicit都有测试,但 cppcheck (1.73) 没有测试 initializer-list。所以 clang-tidy 显式放宽了 initializer-list 的单参数规则。 -
是来自C++11标准,这个宽松的规则吗?
-
@KerrekSB,“正确”的意思(对我来说),它遵循 C++ 标准。构造函数只是一个示例,但是,我可以使用相同的实现创建一个类似的对象来接收真实对象。在这种情况下,我不知道这只是一个样式规则,由谷歌(clang-tidy)还是一个 C++ 规则(cppcheck bug)。
-
C++ 标准允许使用或不使用
explicit关键字来声明任何构造函数。您的代码的两种变体都同样符合。这些工具不检查是否符合标准(编译器会这样做),而是检查样式指南 - 显然,不同的。你一直说cppcheck强制执行你所谓的“C++ 规则”——但请注意它的消息是如何清楚地标记为(style)
标签: c++ c++11 clang static-code-analysis cppcheck