简体   繁体   中英

How do I avoid a conversion operator to invoke the copy constructor?

As part of an optimization/cleanup pass, I'm trying to understand how to reduce temporary copies. While doing this I noticed that a conversion operator invoked my class's copy-constructor which otherwise can be avoided.

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
}

In the following code, the first call to testSet compiles fine, but the second seems to want to invoke the copy constructor.

Adding:

void testSet(CSetViewer &&set) {}

Makes the code compile (VS 2017), but I really don't understand why as I thought that const-reference version would suffice in this situation.

How is the conversion operator different from the GetSetViewer function? Can I make the code above work with the conversion operator without invoking the copy or move constructor?

This is a known bug of Microsoft Visual Studio . A bug report has been filed the 2018-11-12. No news from there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM