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通常比较复杂(较长且较难顺利检查)。他们只是不实现它,而只是为最基本的用例实现它。