C++ 为什么';如果一个雇员完全错了,你不会警告我吗?

C++ 为什么';如果一个雇员完全错了,你不会警告我吗?,c++,c++11,qt-creator,static-analysis,C++,C++11,Qt Creator,Static Analysis,假设我有一对数字的向量: std::vector<std::pair<ulong, ulong>> uniquePairs; 它不会对我大喊大叫。难道不应该有什么东西对我大喊大叫,说这个代码是可怕的,完全错误的吗?根本没有来自门楣的警告 当然,当我使用GCC进行实际编译时,它失败了 如果我这样做: uniquePairs.emplace_back("literal garbage data"); uniquePairs.emplace_back("liter

假设我有一对数字的向量:

std::vector<std::pair<ulong, ulong>> uniquePairs;
它不会对我大喊大叫。难道不应该有什么东西对我大喊大叫,说这个代码是可怕的,完全错误的吗?根本没有来自门楣的警告

当然,当我使用GCC进行实际编译时,它失败了

如果我这样做:

uniquePairs.emplace_back("literal garbage data");
uniquePairs.emplace_back("literal garbage data");
它不会对我大喊大叫

因为它不会检查(执行)这样的语句的正确性


那么,真正的问题是-为什么不这样做?

答案是:因为那通常是大量的工作。让我们来看看这个案例:

uniquePairs.emplace_back("literal garbage data");
试图调用
模板参考位置_back(Args&&…Args)
,其中
Args
是由一种类型组成的参数包-
常量字符[21]
。请记住,
“c-string文本”
对于文本的每一个长度都有不同的类型。这是问题1

问题1: 为使用它调用的所有类型实例化
emplace\u back
s。这工作没那么多,但以后可能会累加起来

所述函数模板的成功实例化导致(根据函数的定义)完美转发,即问题#2

问题2: 调用(实例化)
std::forward
。这只是在重复问题1,但在另一个范围内。不太好,也不可怕

问题3: 在我们已经实例化(在后台,没有完全编译的意图)一些函数模板之后,我们现在需要检查
emplace\u back
的完美转发参数是否可以构造
std::vector
值类型

您的
值类型是
std::pair
。显然,
const char[21]
无法做到这一点。你的IDE现在可以向你尖叫了


这是一个相当琐碎的案例,但请注意一开始需要做多少工作。现在想象一下,你是完美的转发其他东西。更多的争论。更多的电话。更多的后台实例

背景代码消毒剂不应该打断你的工作。他们也应该(希望)在合理的时间内给你可靠的提示。这个特性可能非常琐碎(您的情况)或非常复杂。简单的答案就是不要试图完成这些任务

奖金: 那么,为什么如果你
推回(“文字垃圾数据”)
,IDE通常会对你大喊大叫


因为
push_-back
的签名对于
std::vector
采用
const T&
T&
。看到
constchar[21]
不是
std::pair
(两者都不能转换为一)是非常简单的。不需要实例化(前提是
向量的实例化已经在后台完成。如果没有,则为这两种情况添加另一个问题)。没有很多工作。易于计算,易于警告。

这需要您的后台代码分析器为模板实例化等执行大量工作。这是困难的,因为间接层次-你完美地将
emplace\u的参数转发回了
。哪个版本?使用铿锵代码模型?安放背面的签名是一个可以接受任何东西的函数。很难说你的输入会不好。
std::vector::emplace\u back
接受一个参数包,即
template void emplace\u back(类型和类型){…}
。然后它将它们完美地转发到向量中,以构造
值\u type
std::pair
)。要工作,它必须:1)从签名(
const char[21]
)实例化
emplace\u back
函数,2)用相同的东西实例化
std::forward
,3)检查是否可以用该结果构造
value\u type
。这可能需要做很多工作。不一定在这里,但在一般情况下,事情可能会层叠得更深。它必须在您每次回电话时重复整个过程。即使你的
“文字量”
只有一个
char
acter off。当通过引用传递时,这些是不同的类型。编辑:“这难道不能把“任何东西”缩小到构造[…]所需的参数范围吗?”——不管我刚才解释的工作量有多大,这个案例都是非常琐碎的。一般情况下,mroe通常比较复杂(较长且较难顺利检查)。他们只是不实现它,而只是为最基本的用例实现它。