【发布时间】:2019-01-28 17:43:13
【问题描述】:
作为优化/清理过程的一部分,我试图了解如何减少临时副本。在执行此操作时,我注意到转换运算符调用了我的类的复制构造函数,否则可以避免。
struct CSetViewer
{
int s;
CSetViewer(int size) : s(size) {}
CSetViewer(const CSetViewer &) = delete;
CSetViewer &operator=(const CSetViewer &) = delete;
CSetViewer(CSetViewer &&) = delete;
CSetViewer &operator=(CSetViewer &&) = delete;
};
struct CSet
{
operator CSetViewer() { return {1}; }
CSetViewer GetSetViewer() { return {1}; }
};
void testSet(const CSetViewer &set) {}
void main()
{
CSet set;
testSet(set.GetSetViewer());
testSet(set); // Error: attempting to reference a deleted function
}
在下面的代码中,第一次调用 testSet 编译正常,但第二次似乎想要调用复制构造函数。
添加:
void testSet(CSetViewer &&set) {}
使代码编译(VS 2017),但我真的不明白为什么,因为我认为 const-reference 版本在这种情况下就足够了。
转换运算符与 GetSetViewer 函数有何不同?我可以在不调用复制或移动构造函数的情况下使上面的代码与转换运算符一起使用吗?
【问题讨论】:
-
您使用的是什么 C++ 标准(在 MSVC 上,这是
/std:标志)? -
GCC 从 c++11 开始接受此代码(好吧,
s/void main/int main/):coliru.stacked-crooked.com/a/37ea3caefd1d9aae。 clang 也是如此:coliru.stacked-crooked.com/a/9cf791bd7b941d98. -
有趣。所有三种可用的语言标准(14/17/最新)在 VS 2017 中都失败了。
-
确实:godbolt.org/z/oDeboI 看起来像一个编译器错误