Implicit conversion and functional operators
I'm studying functional operators and can't understand why code snippets like this compile:
class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};
int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}
My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.
So what am I missing?
c++ implicit-conversion
add a comment |
I'm studying functional operators and can't understand why code snippets like this compile:
class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};
int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}
My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.
So what am I missing?
c++ implicit-conversion
1
The compiler will deduce a possible conversion forminus()using the explicit cast operator ofPocket.
– πάντα ῥεῖ
Jan 1 at 11:26
Where did you gather the user defined conversion isn't going to come into play?
– StoryTeller
Jan 1 at 11:27
"and a conversion toint, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?
– πάντα ῥεῖ
Jan 1 at 11:32
4
Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove theoperator intfrom thePocketclass - you will see that the code no longer compiles.
– Peter
Jan 1 at 11:33
add a comment |
I'm studying functional operators and can't understand why code snippets like this compile:
class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};
int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}
My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.
So what am I missing?
c++ implicit-conversion
I'm studying functional operators and can't understand why code snippets like this compile:
class Pocket
{
int value;
public:
Pocket(int value) :value(value) {}
int getValue() const
{
return value;
}
operator int() const
{
return value;
}
bool operator<(const Pocket & _Right) const
{
return value < _Right.value;
}
};
int main() {
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
vector<Pocket> v3(5, 0);
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
return 0;
}
My reasoning is that when you call the minus<Pocket> operator inside transform, the whole thing would reduce to a subtraction between two Pockets. As you can see, the class doesn't defines a proper operator-, only an operator<, which should be useless in this case, and a conversion to int, which shouldn't even be considered since both arguments are of the same type.
So what am I missing?
c++ implicit-conversion
c++ implicit-conversion
asked Jan 1 at 11:24
Andrea BoccoAndrea Bocco
44913
44913
1
The compiler will deduce a possible conversion forminus()using the explicit cast operator ofPocket.
– πάντα ῥεῖ
Jan 1 at 11:26
Where did you gather the user defined conversion isn't going to come into play?
– StoryTeller
Jan 1 at 11:27
"and a conversion toint, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?
– πάντα ῥεῖ
Jan 1 at 11:32
4
Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove theoperator intfrom thePocketclass - you will see that the code no longer compiles.
– Peter
Jan 1 at 11:33
add a comment |
1
The compiler will deduce a possible conversion forminus()using the explicit cast operator ofPocket.
– πάντα ῥεῖ
Jan 1 at 11:26
Where did you gather the user defined conversion isn't going to come into play?
– StoryTeller
Jan 1 at 11:27
"and a conversion toint, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?
– πάντα ῥεῖ
Jan 1 at 11:32
4
Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove theoperator intfrom thePocketclass - you will see that the code no longer compiles.
– Peter
Jan 1 at 11:33
1
1
The compiler will deduce a possible conversion for
minus() using the explicit cast operator of Pocket.– πάντα ῥεῖ
Jan 1 at 11:26
The compiler will deduce a possible conversion for
minus() using the explicit cast operator of Pocket.– πάντα ῥεῖ
Jan 1 at 11:26
Where did you gather the user defined conversion isn't going to come into play?
– StoryTeller
Jan 1 at 11:27
Where did you gather the user defined conversion isn't going to come into play?
– StoryTeller
Jan 1 at 11:27
"and a conversion to
int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?– πάντα ῥεῖ
Jan 1 at 11:32
"and a conversion to
int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?– πάντα ῥεῖ
Jan 1 at 11:32
4
4
Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the
operator int from the Pocket class - you will see that the code no longer compiles.– Peter
Jan 1 at 11:33
Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the
operator int from the Pocket class - you will see that the code no longer compiles.– Peter
Jan 1 at 11:33
add a comment |
1 Answer
1
active
oldest
votes
The user-defined conversion function which makes the following initializations possible in your code:
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
will also be used by the compiler in the transform call when applying the minus to the given range :
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.
However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.
The relevant section in the standard for this:
15.3.2 Conversion functions [class.conv.fct]
...
2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995030%2fimplicit-conversion-and-functional-operators%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The user-defined conversion function which makes the following initializations possible in your code:
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
will also be used by the compiler in the transform call when applying the minus to the given range :
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.
However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.
The relevant section in the standard for this:
15.3.2 Conversion functions [class.conv.fct]
...
2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.
add a comment |
The user-defined conversion function which makes the following initializations possible in your code:
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
will also be used by the compiler in the transform call when applying the minus to the given range :
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.
However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.
The relevant section in the standard for this:
15.3.2 Conversion functions [class.conv.fct]
...
2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.
add a comment |
The user-defined conversion function which makes the following initializations possible in your code:
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
will also be used by the compiler in the transform call when applying the minus to the given range :
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.
However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.
The relevant section in the standard for this:
15.3.2 Conversion functions [class.conv.fct]
...
2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.
The user-defined conversion function which makes the following initializations possible in your code:
Pocket mynumbers1 = { 3, 9, 2, -4, 4 };
Pocket mynumbers2 = { 3, 9, 5, 0, 4 };
will also be used by the compiler in the transform call when applying the minus to the given range :
transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
If you were to remove the operator int() const conversion function neither the initializations nor the transform would work.
However, if you were to make the conversion function explicit, it would work for initializations but not for the transform. See demo here.
The relevant section in the standard for this:
15.3.2 Conversion functions [class.conv.fct]
...
2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.
answered Jan 2 at 6:10
P.WP.W
16.2k31455
16.2k31455
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995030%2fimplicit-conversion-and-functional-operators%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown

1
The compiler will deduce a possible conversion for
minus()using the explicit cast operator ofPocket.– πάντα ῥεῖ
Jan 1 at 11:26
Where did you gather the user defined conversion isn't going to come into play?
– StoryTeller
Jan 1 at 11:27
"and a conversion to
int, which shouldn't even be considered since both arguments are of the same type" This statement is very unclear, can you elaborate more please why you think this should apply?– πάντα ῥεῖ
Jan 1 at 11:32
4
Your reasoning is incorrect - the compiler will use the user-defined conversion you have specified. To demonstrate that, remove the
operator intfrom thePocketclass - you will see that the code no longer compiles.– Peter
Jan 1 at 11:33