我刚刚在我的代码中找到了一个错误,因为这是一个简单的签名/无符号的不匹配,所以我感到很困惑 - 根本不应该发生,因为我正在编译有警告4,警告是错误。所以我试图复制它,这很简单:
#include <memory>
class MyClass {
public:
MyClass( unsigned ) {}
};
int main()
{
MyClass* rawP = new MyClass(-1); // issues a warning, as expected
auto uniqueP = std::make_unique<MyClass>(-1); // NO WARNING??!
// silence the compiler
rawP;
uniqueP;
return 0;
}
现在我在问自己:这是什么原因?它是VS中的错误,还是STD :: make_unique的一般缺点?有什么方法可以解决吗?(Visual Studio 2015社区更新3(
您看到了几种效果的组合。
- 您的
main()
中的呼叫是完全合法的,因为make_unique
模板实例化匹配您送达的签名数据类型。 -
make_unique
的实施不会产生警告,因为警告通常在系统标题内禁用。 - Visual Studio似乎无法检测到电位(但没有确定(
make_unique
中的标志转换问题。
更详细地:
1。模板实例化实际上是合法的。
std::make_unique
的典型实现看起来像这样(比较cppreference(:
template <typename T, typename... Args>
inline std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
在您的情况下,当您致电std::make_unique<MyClass>(-1)
时,模板为实例化用于a 签名整数。因此,您不会在您的代码,因为没有未签名/签名的转换发生。
2。系统标头通常禁用警告。
但是,您可以正确地期望从make_unique
发出警告执行。毕竟,当您的签名调用new T(...)
时参数,签名/未签名的转换仍会发生。作为一个例子,以以下程序:
#include <memory>
class MyClass
{
public:
MyClass(unsigned) { }
};
template <typename T, typename... Args>
inline std::unique_ptr<T> custom_make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
int main()
{
auto uniqueP = custom_make_unique<MyClass>(-1);
(void) uniqueP;
return 0;
}
当我使用-Wsign-conversion
使用GCC对此进行编译时,我会得到警告
test.cpp:在'std :: simolor_ptr&lt; _tp> custom_make_unique(args&amp;&amp; ...([with t = myClass;args = {int}]':
test.cpp:17:48:此处需要
test.cpp:12:63:警告:从" int"中转换为" unsigned int"可能会改变结果的迹象[-wsign-conversion]
返回std :: unique_ptr(new T(std :: forthrom(args(...((;
所以问题是,为什么您没有对std::make_unique()
的警告执行?答案本质上是编译器沉默这些警告其系统标头。例如,<memory>
的GCC版本标头包含Pragma
#pragma GCC system_header
一旦该布拉格出现在标题文件中,编译器就不再报告该标头内所有内容的警告。从GCC文档:
标题文件将接口声明为操作系统和运行时 图书馆通常不能用严格符合C写成C。因此,GCC 提供在系统标头中找到的特殊处理中的代码。所有警告,除了 由"
#warning
"生成的那些(请参阅诊断(,而GCC为 处理系统标头。
另请参阅这个帖子更多细节。据推测,Visual Studio的方法类似编译器(正如您在评论中所写的那样,标题暂时减少警告级别(。
3。看起来您正在遇到VisualStudio限制。
在VisualStudio的情况下,还有其他工作。注意如何上面的海湾合作委员会警告说, May 是一个标志转换问题(取决于关于哪些价值用户将稍后 feed到 custom_make_unique
(。它出现该VisualStudio只有在存在确定的标志转换问题时才警告。请参阅以下程序:
#include <iostream>
void f(unsigned) { }
template <typename T>
void g(T val) { f(val); } // GCC issues a warning, VS does NOT
int main()
{
f(-1); // GCC and VS issue a warning
g(-1); // no conversion warning here (g<int> instantiated)
}
在线尝试。