下面的代码
void f(const std::string &s = {}) {
}
f();
在 Visual Studio 2013(调试版本)中生成 Debug Assertion Failed(无效的空指针)
。它在 gcc 中运行正常(我可以得到 s.length()
为 0)。尝试构造 s
时看起来像一个错误:
这是调用堆栈:
框架:
f(); <-- HERE --
框架(xstring):
basic_string(const _Elem *_Ptr)
: _Mybase()
{ // construct from [_Ptr, <null>)
_Tidy();
assign(_Ptr); // <-- HERE --
}
框架(xstring):
_Myt& assign(const _Elem *_Ptr)
{ // assign [_Ptr, <null>)
_DEBUG_POINTER(_Ptr); <-- HERE --
return (assign(_Ptr, _Traits::length(_Ptr)));
}
框架(实用程序):
template<class _Ty> inline
void _Debug_pointer(const _Ty *_First, _Dbfile_t _File, _Dbline_t _Line)
{ // test iterator for non-singularity, const pointers
if (_First == 0)
_DEBUG_ERROR2("invalid null pointer", _File, _Line); <-- HERE --
}
看起来它使用 (const char *)
而不是默认构造函数来调用构造函数。
当我尝试这样做时:
std::string x = {}; // local variable
它调用默认构造函数。
这是 Visual Studio 上的错误还是我遗漏了什么?
我知道解决方法是 void f(const std::string &s = "")
,但我想使用默认初始化程序,这是一个非常奇怪的行为。
最佳答案
这是一个错误。
如果这不是错误,那么您应该会收到构造函数不明确错误,因为调用的构造函数不是默认构造函数,而可以调用默认构造函数。
以下代码使用 Visual C++ 12.0(Visual Studio 2013 附带的编译器)编译:
struct X
{
X( char const* ) {}
};
void g( X const& = {} ) {}
它不应该编译。
以下代码,其中构造函数参数不可默认构造,无法编译:
struct Y
{
struct E { E( int ){} };
Y( E ) {}
};
void h( Y const& = {} ) {}
带有枚举类型构造函数参数的中间情况确实可以编译,因此显然初始化器 {}
没有转换为 {0}
,而是转换为 { {}}
– 如果我可能会猜测,也许是为了抑制 std::array
初始化的警告?
我已经提交了 bug report给微软。
关于c++ - 调试断言失败(无效的空指针)默认字符串参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23709584/