Strange behavior of operator type

Started by
22 comments, last by Aardvajk 10 years, 2 months ago

And before you start to explain what i should and what i shouldn't do in code, i know this, i have more than 13 years professional c++ experience, and more than 7 on lead position. Yes i do know which problems this code can create. And yes i know how to fix them.


I'm used to lead programmers being selected based on interpersonal skills, and their focus on things like code standards, readability, and maintainability. I suppose different companies have different criteria.

You can do whatever you want in your code, but if you expect to post some strange C++ construct to GameDev and just get a question answered, without getting lectured on the community's near-consensus right way to use C++, you aren't very experienced here.
Advertisement

Interestingly, I find this abomination also compiles on GCC 4.7.2 (a from-source build we use at work). So does:


class SomeType
{
public:
    operator std::string(){ return std::string(); }
    operator const char*(){ return 0; }
};

void f(SomeType s)
{
    std::string x = s;
}

I'll have to leave it to the standards experts to explain this. To me that assignment is ambiguous as it equates to:

std::string x(s);

Which then consults std::string to see if it can be constructed from SomeType or from a type SomeType can be converted to. Since this should yield two candidate constructors on std::string, this to me should be ambiguous.

So I have no idea which compiler has the defect. I know which programmer does though.

Interestingly, I find this abomination also compiles on GCC 4.7.2 (a from-source build we use at work). So does:


class SomeType
{
public:
    operator std::string(){ return std::string(); }
    operator const char*(){ return 0; }
};

void f(SomeType s)
{
    std::string x = s;
}
I'll have to leave it to the standards experts to explain this. To me that assignment is ambiguous as it equates to:

std::string x(s);

Which then consults std::string to see if it can be constructed from SomeType or from a type SomeType can be converted to. Since this should yield two candidate constructors on std::string, this to me should be ambiguous.

So I have no idea which compiler has the defect. I know which programmer does though.

It's pretty clear that in that context, you would always want operator std::string to fire. The char * constructor converts a char pointer to a string, effectively going from sometype to char * to std::string. The copy constructor is a function call, but it's not a conversion, you're going strait to std::string without another type in the middle. So you always want to call the copy constructor (which can the be elided away). And C++ has that rule apparently.

Interestingly, I find this abomination also compiles on GCC 4.7.2 (a from-source build we use at work). So does:


class SomeType
{
public:
    operator std::string(){ return std::string(); }
    operator const char*(){ return 0; }
};

void f(SomeType s)
{
    std::string x = s;
}
I'll have to leave it to the standards experts to explain this. To me that assignment is ambiguous as it equates to:

std::string x(s);

Which then consults std::string to see if it can be constructed from SomeType or from a type SomeType can be converted to. Since this should yield two candidate constructors on std::string, this to me should be ambiguous.

So I have no idea which compiler has the defect. I know which programmer does though.

It's pretty clear that in that context, you would always want operator std::string to fire. The char * constructor converts a char pointer to a string, effectively going from sometype to char * to std::string. The copy constructor is a function call, but it's not a conversion, you're going strait to std::string without another type in the middle. So you always want to call the copy constructor (which can the be elided away). And C++ has that rule apparently.

So the compiler must be seeing if the type can be converted to std::string before it is seeing if it can be converted to any of the types that can be passed to a std::string constructor?

Standards experts, is this correct behaviour?

This topic is closed to new replies.

Advertisement