Jens Andersson
Jens Andersson

Reputation: 129

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?

Upvotes: 4

Views: 162

Answers (1)

YSC
YSC

Reputation: 40080

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

Upvotes: 3

Related Questions