在 VS2015 C++ 中处理 `default` 关键字的可能错误
Possible bug in handling the `default` keyword in VS2015 C++
在测试 VS2015 C++ 编译器时,我偶然发现了一个带有 default
关键字的奇怪错误。如果我这样做:
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
我明白了
error C2280: 'Dummy::Dummy(const Dummy &)': attempting to reference a deleted function
note: see declaration of 'Dummy::Dummy'
但是如果我使用一个空的构造函数
struct Dummy
{
Dummy() {}
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
代码编译。 运行 带有 g++ or clang 的第一个示例不会产生错误。
为什么在 VS2015 中使用默认构造函数会尝试在 g++ 或 clang 中不使用的复制构造函数?
这绝对是 VS 2015 中的一个错误。
在 C++11 中,将 temporary 分配给 const 引用不得调用复制构造函数,但 VS 2015 会调用。
你可以用
查看
#include <iostream>
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) { std::cout << "copy ctor" << std::endl; }
void test() const { std::cout << "test" << std::endl; }
};
int main()
{
const Dummy& ref = Dummy();
ref.test();
return 0;
}
在 VS 2013、2015、gcc 和 clang 上编译。只有 VS(任何版本)调用复制构造函数,如果 class 构造函数定义为 = default
.
我认为 VS 编译器在 2015 年仍然错误地使用旧的 C++03 标准规则(C++03 的 8.5.3.5):
If the initializer expression is an rvalue, with T2 a class type, and
"cv1 T1" is reference-compatible with "cv2 T2," the reference is bound
in one of the following ways (the choice is implementation-defined):
-- The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.
-- A temporary of type "cv1 T2" [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The
reference is bound to the temporary or to a sub-object within the
temporary.
The constructor that would be used to make the copy shall be callable
whether or not the copy is actually done.
VS开发者选择了第二种方式。他们针对空的用户定义构造函数 ({}
) 更正了此问题,但忘记为默认 (= default
) 构造函数执行此操作。
PS。 Bug on MS Connect(请投票)
在测试 VS2015 C++ 编译器时,我偶然发现了一个带有 default
关键字的奇怪错误。如果我这样做:
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
我明白了
error C2280: 'Dummy::Dummy(const Dummy &)': attempting to reference a deleted function
note: see declaration of 'Dummy::Dummy'
但是如果我使用一个空的构造函数
struct Dummy
{
Dummy() {}
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
代码编译。 运行 带有 g++ or clang 的第一个示例不会产生错误。
为什么在 VS2015 中使用默认构造函数会尝试在 g++ 或 clang 中不使用的复制构造函数?
这绝对是 VS 2015 中的一个错误。
在 C++11 中,将 temporary 分配给 const 引用不得调用复制构造函数,但 VS 2015 会调用。
你可以用
查看#include <iostream>
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) { std::cout << "copy ctor" << std::endl; }
void test() const { std::cout << "test" << std::endl; }
};
int main()
{
const Dummy& ref = Dummy();
ref.test();
return 0;
}
在 VS 2013、2015、gcc 和 clang 上编译。只有 VS(任何版本)调用复制构造函数,如果 class 构造函数定义为 = default
.
我认为 VS 编译器在 2015 年仍然错误地使用旧的 C++03 标准规则(C++03 的 8.5.3.5):
If the initializer expression is an rvalue, with T2 a class type, and "cv1 T1" is reference-compatible with "cv2 T2," the reference is bound in one of the following ways (the choice is implementation-defined):
-- The reference is bound to the object represented by the rvalue (see 3.10) or to a sub-object within that object.
-- A temporary of type "cv1 T2" [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. The reference is bound to the temporary or to a sub-object within the temporary.
The constructor that would be used to make the copy shall be callable whether or not the copy is actually done.
VS开发者选择了第二种方式。他们针对空的用户定义构造函数 ({}
) 更正了此问题,但忘记为默认 (= default
) 构造函数执行此操作。
PS。 Bug on MS Connect(请投票)