我有一个模板类属性,它包装了其他类型:
template <typename T>
class Property
{
private:
T value;
public:
Property() = default;
Property(const T& initialValue)
: value(initialValue) {}
virtual ~Property() = default;
//Make this class non-copyable.
Property(const Property&) = delete;
Property& operator=(const Property&) = delete;
virtual Property& operator=(const T& other)
{
value = other;
return *this;
}
//... a bunch of other unimportant stuff
}
Visual Studio 15.7.6和其他一些编译器对此非常满意
{ //function or class definition (default member initialization)
Property<int> prop = 5;
}
然而,(针对专有编译目标稍作修改)以上声明,GCC 4.9.4失败:
Error GD4849D22 use of deleted function
'Property<T>::Property(const Property<T>&) [with T = int]'
编译器似乎正在尝试构造一个RValue属性,然后使用已删除的复制构造函数,而不是简单地使用类型适当的构造函数。
这是GCC过于谨慎的表现吗?
Property<int> prop(5); //explicit constructor call - valid with GCC Compiler
Property<int> myOtherProp;
myOtherProp = 5; //Also fine (obviously)
或者,这是一个MSVC玩得不定,做一些标准说它不应该或没有必要做的事情的情况?
不幸的是,我不能更新我的GCC版本。因为存在变通方法,所以我更多地是在寻找“为什么”会发生这种情况。
发布于 2018-09-12 06:56:27
我相信这里发生的事情是guaranteed copy elision在工作(这是C++17的一个特性)。像这样的成员声明
struct A
{
Property<int> prop = 5;
};
表示成员将通过复制初始化进行初始化。首先,使用转换构造函数从5
构造一个临时的Property
对象,然后从该对象构造实际的属性。由于Property
不可移动,因此将调用复制构造函数,该构造函数将被删除。虽然编译器甚至在C++17之前就被允许elide this copy (任何合理的编译器,因为基本上永远都会这样做),但它仍然需要强制执行所有约束,例如任何必要的构造函数的存在和可访问性,就像制作了副本一样。C++17取消了所有这些,基本上是强制复制省略。
https://stackoverflow.com/questions/52285048
复制相似问题