How to specialize templated operator overloads?
I'm trying to overload comparison operators as non-members for a particular templated class sub
, 1) between instances of sub
, and 2) between sub
and a specific variable, which returns an instance of either comparer_sub
for the first case and comparer_el
in the alternative, which perform comparisons on sub
along with some other useful members:
template <typename T1, typename T2>
class sub_base
public:
sub_base() ;
;
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub getSub() return sub();;
;
template <typename T1,typename T2>
class comparer_base
public:
comparer_base() ;
void base_method() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
class comparer_sub : public comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>
using comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>::base_method;
public:
comparer_sub() : comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>() ;
;
template <typename lT1,typename lT2,typename rT>
class comparer_el : public comparer_base<sub_base<lT1,lT2>,rT>
using comparer_base<sub_base<lT1,lT2>,rT>::base_method;
public:
comparer_el() : comparer_base<sub_base<lT1,lT2>,rT>() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
comparer_sub<lT1,lT2,rT1,rT2> operator== (const sub_base<lT1,lT2>& lhs, const sub_base<rT1,rT2>& rhs)
printf("comparer_subn");
return comparer_sub<lT1,lT2,rT1,rT2>();
;
template <typename lT1,typename lT2,typename rT>
comparer_el<lT1,lT2,rT> operator== (const sub_base<lT1,lT2>& lhs, const rT& rhs)
printf("comparer_eln");
return comparer_el<lT1,lT2,rT>();
;
However, any type of comparison I try to perform the second overload is called, what I assume is due to const rt&
being too generic and any instance of sub
fits that argument.
int main(int argc, char const *argv)
mat<int> A;
mat<float> B;
float C = 0.6;
A.getSub() == B.getSub(); // comparer_el
A.getSub() == C; // comparer_el
return 0;
How can I force the first overload to be prioritized over the second overload between instances of sub
??
c++ templates operator-overloading
|
show 2 more comments
I'm trying to overload comparison operators as non-members for a particular templated class sub
, 1) between instances of sub
, and 2) between sub
and a specific variable, which returns an instance of either comparer_sub
for the first case and comparer_el
in the alternative, which perform comparisons on sub
along with some other useful members:
template <typename T1, typename T2>
class sub_base
public:
sub_base() ;
;
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub getSub() return sub();;
;
template <typename T1,typename T2>
class comparer_base
public:
comparer_base() ;
void base_method() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
class comparer_sub : public comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>
using comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>::base_method;
public:
comparer_sub() : comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>() ;
;
template <typename lT1,typename lT2,typename rT>
class comparer_el : public comparer_base<sub_base<lT1,lT2>,rT>
using comparer_base<sub_base<lT1,lT2>,rT>::base_method;
public:
comparer_el() : comparer_base<sub_base<lT1,lT2>,rT>() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
comparer_sub<lT1,lT2,rT1,rT2> operator== (const sub_base<lT1,lT2>& lhs, const sub_base<rT1,rT2>& rhs)
printf("comparer_subn");
return comparer_sub<lT1,lT2,rT1,rT2>();
;
template <typename lT1,typename lT2,typename rT>
comparer_el<lT1,lT2,rT> operator== (const sub_base<lT1,lT2>& lhs, const rT& rhs)
printf("comparer_eln");
return comparer_el<lT1,lT2,rT>();
;
However, any type of comparison I try to perform the second overload is called, what I assume is due to const rt&
being too generic and any instance of sub
fits that argument.
int main(int argc, char const *argv)
mat<int> A;
mat<float> B;
float C = 0.6;
A.getSub() == B.getSub(); // comparer_el
A.getSub() == C; // comparer_el
return 0;
How can I force the first overload to be prioritized over the second overload between instances of sub
??
c++ templates operator-overloading
@user1810087 I've edited the question, needed to callgetSub()
on comparison types.
– joaocandre
Nov 13 '18 at 15:30
now it does compile :) BTW, i did not downvote your question... counter +1, because the question is interesting...
– user1810087
Nov 13 '18 at 15:36
Cannot put it into good words right now, but the problem is,comparer_el
with the second parameter beeing substituted fromsub
totypename rT2
is a better choise as the substitution+cast fromsub
tosub_base<rT1,rT2>
. Substitution does not implicitly cast... So, one solution is not to use return typesub
withgetSub()
but the base typesub_base<rT1,rT2>
. see here, only change line 22
– user1810087
Nov 13 '18 at 15:50
Also, return typesub_base<rT1,rT2>
should be prefered as classsub
is nested and only known inside class mat...
– user1810087
Nov 13 '18 at 15:59
Fair enough, I think I've understood the problem. The whole reason I nested classsub
was to simplify the syntax and avoid trailing template arguments (the actual code is quite cluttered and hard to "read" as it is) - would a templated typedef work in this case?
– joaocandre
Nov 13 '18 at 16:04
|
show 2 more comments
I'm trying to overload comparison operators as non-members for a particular templated class sub
, 1) between instances of sub
, and 2) between sub
and a specific variable, which returns an instance of either comparer_sub
for the first case and comparer_el
in the alternative, which perform comparisons on sub
along with some other useful members:
template <typename T1, typename T2>
class sub_base
public:
sub_base() ;
;
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub getSub() return sub();;
;
template <typename T1,typename T2>
class comparer_base
public:
comparer_base() ;
void base_method() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
class comparer_sub : public comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>
using comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>::base_method;
public:
comparer_sub() : comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>() ;
;
template <typename lT1,typename lT2,typename rT>
class comparer_el : public comparer_base<sub_base<lT1,lT2>,rT>
using comparer_base<sub_base<lT1,lT2>,rT>::base_method;
public:
comparer_el() : comparer_base<sub_base<lT1,lT2>,rT>() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
comparer_sub<lT1,lT2,rT1,rT2> operator== (const sub_base<lT1,lT2>& lhs, const sub_base<rT1,rT2>& rhs)
printf("comparer_subn");
return comparer_sub<lT1,lT2,rT1,rT2>();
;
template <typename lT1,typename lT2,typename rT>
comparer_el<lT1,lT2,rT> operator== (const sub_base<lT1,lT2>& lhs, const rT& rhs)
printf("comparer_eln");
return comparer_el<lT1,lT2,rT>();
;
However, any type of comparison I try to perform the second overload is called, what I assume is due to const rt&
being too generic and any instance of sub
fits that argument.
int main(int argc, char const *argv)
mat<int> A;
mat<float> B;
float C = 0.6;
A.getSub() == B.getSub(); // comparer_el
A.getSub() == C; // comparer_el
return 0;
How can I force the first overload to be prioritized over the second overload between instances of sub
??
c++ templates operator-overloading
I'm trying to overload comparison operators as non-members for a particular templated class sub
, 1) between instances of sub
, and 2) between sub
and a specific variable, which returns an instance of either comparer_sub
for the first case and comparer_el
in the alternative, which perform comparisons on sub
along with some other useful members:
template <typename T1, typename T2>
class sub_base
public:
sub_base() ;
;
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub getSub() return sub();;
;
template <typename T1,typename T2>
class comparer_base
public:
comparer_base() ;
void base_method() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
class comparer_sub : public comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>
using comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>::base_method;
public:
comparer_sub() : comparer_base<sub_base<lT1,lT2>,sub_base<rT1,rT2>>() ;
;
template <typename lT1,typename lT2,typename rT>
class comparer_el : public comparer_base<sub_base<lT1,lT2>,rT>
using comparer_base<sub_base<lT1,lT2>,rT>::base_method;
public:
comparer_el() : comparer_base<sub_base<lT1,lT2>,rT>() ;
;
template <typename lT1,typename lT2,typename rT1,typename rT2>
comparer_sub<lT1,lT2,rT1,rT2> operator== (const sub_base<lT1,lT2>& lhs, const sub_base<rT1,rT2>& rhs)
printf("comparer_subn");
return comparer_sub<lT1,lT2,rT1,rT2>();
;
template <typename lT1,typename lT2,typename rT>
comparer_el<lT1,lT2,rT> operator== (const sub_base<lT1,lT2>& lhs, const rT& rhs)
printf("comparer_eln");
return comparer_el<lT1,lT2,rT>();
;
However, any type of comparison I try to perform the second overload is called, what I assume is due to const rt&
being too generic and any instance of sub
fits that argument.
int main(int argc, char const *argv)
mat<int> A;
mat<float> B;
float C = 0.6;
A.getSub() == B.getSub(); // comparer_el
A.getSub() == C; // comparer_el
return 0;
How can I force the first overload to be prioritized over the second overload between instances of sub
??
c++ templates operator-overloading
c++ templates operator-overloading
edited Nov 13 '18 at 15:29
joaocandre
asked Nov 13 '18 at 15:15
joaocandrejoaocandre
4921023
4921023
@user1810087 I've edited the question, needed to callgetSub()
on comparison types.
– joaocandre
Nov 13 '18 at 15:30
now it does compile :) BTW, i did not downvote your question... counter +1, because the question is interesting...
– user1810087
Nov 13 '18 at 15:36
Cannot put it into good words right now, but the problem is,comparer_el
with the second parameter beeing substituted fromsub
totypename rT2
is a better choise as the substitution+cast fromsub
tosub_base<rT1,rT2>
. Substitution does not implicitly cast... So, one solution is not to use return typesub
withgetSub()
but the base typesub_base<rT1,rT2>
. see here, only change line 22
– user1810087
Nov 13 '18 at 15:50
Also, return typesub_base<rT1,rT2>
should be prefered as classsub
is nested and only known inside class mat...
– user1810087
Nov 13 '18 at 15:59
Fair enough, I think I've understood the problem. The whole reason I nested classsub
was to simplify the syntax and avoid trailing template arguments (the actual code is quite cluttered and hard to "read" as it is) - would a templated typedef work in this case?
– joaocandre
Nov 13 '18 at 16:04
|
show 2 more comments
@user1810087 I've edited the question, needed to callgetSub()
on comparison types.
– joaocandre
Nov 13 '18 at 15:30
now it does compile :) BTW, i did not downvote your question... counter +1, because the question is interesting...
– user1810087
Nov 13 '18 at 15:36
Cannot put it into good words right now, but the problem is,comparer_el
with the second parameter beeing substituted fromsub
totypename rT2
is a better choise as the substitution+cast fromsub
tosub_base<rT1,rT2>
. Substitution does not implicitly cast... So, one solution is not to use return typesub
withgetSub()
but the base typesub_base<rT1,rT2>
. see here, only change line 22
– user1810087
Nov 13 '18 at 15:50
Also, return typesub_base<rT1,rT2>
should be prefered as classsub
is nested and only known inside class mat...
– user1810087
Nov 13 '18 at 15:59
Fair enough, I think I've understood the problem. The whole reason I nested classsub
was to simplify the syntax and avoid trailing template arguments (the actual code is quite cluttered and hard to "read" as it is) - would a templated typedef work in this case?
– joaocandre
Nov 13 '18 at 16:04
@user1810087 I've edited the question, needed to call
getSub()
on comparison types.– joaocandre
Nov 13 '18 at 15:30
@user1810087 I've edited the question, needed to call
getSub()
on comparison types.– joaocandre
Nov 13 '18 at 15:30
now it does compile :) BTW, i did not downvote your question... counter +1, because the question is interesting...
– user1810087
Nov 13 '18 at 15:36
now it does compile :) BTW, i did not downvote your question... counter +1, because the question is interesting...
– user1810087
Nov 13 '18 at 15:36
Cannot put it into good words right now, but the problem is,
comparer_el
with the second parameter beeing substituted from sub
to typename rT2
is a better choise as the substitution+cast from sub
to sub_base<rT1,rT2>
. Substitution does not implicitly cast... So, one solution is not to use return type sub
with getSub()
but the base type sub_base<rT1,rT2>
. see here, only change line 22– user1810087
Nov 13 '18 at 15:50
Cannot put it into good words right now, but the problem is,
comparer_el
with the second parameter beeing substituted from sub
to typename rT2
is a better choise as the substitution+cast from sub
to sub_base<rT1,rT2>
. Substitution does not implicitly cast... So, one solution is not to use return type sub
with getSub()
but the base type sub_base<rT1,rT2>
. see here, only change line 22– user1810087
Nov 13 '18 at 15:50
Also, return type
sub_base<rT1,rT2>
should be prefered as class sub
is nested and only known inside class mat...– user1810087
Nov 13 '18 at 15:59
Also, return type
sub_base<rT1,rT2>
should be prefered as class sub
is nested and only known inside class mat...– user1810087
Nov 13 '18 at 15:59
Fair enough, I think I've understood the problem. The whole reason I nested class
sub
was to simplify the syntax and avoid trailing template arguments (the actual code is quite cluttered and hard to "read" as it is) - would a templated typedef work in this case?– joaocandre
Nov 13 '18 at 16:04
Fair enough, I think I've understood the problem. The whole reason I nested class
sub
was to simplify the syntax and avoid trailing template arguments (the actual code is quite cluttered and hard to "read" as it is) - would a templated typedef work in this case?– joaocandre
Nov 13 '18 at 16:04
|
show 2 more comments
1 Answer
1
active
oldest
votes
The problem is, comparer_el
with rT=sub
is a better choise than the substitution+cast from sub
to sub_base<rT1,rT2>
. Deduction does not implicitly cast (except putting additional c/v qualifiers)... For a much better description, read this answer.
So, one solution is not to use return type sub
within getSub()
but the base type sub_base<rT1,rT2>
. see here
important part:
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub_base<T,mat<T>> getSub() return sub();;
// ^^^^^^^^^^^^^^^^^^ return type changed from sub to sub_base<T,mat<T>>
;
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%2f53284069%2fhow-to-specialize-templated-operator-overloads%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 problem is, comparer_el
with rT=sub
is a better choise than the substitution+cast from sub
to sub_base<rT1,rT2>
. Deduction does not implicitly cast (except putting additional c/v qualifiers)... For a much better description, read this answer.
So, one solution is not to use return type sub
within getSub()
but the base type sub_base<rT1,rT2>
. see here
important part:
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub_base<T,mat<T>> getSub() return sub();;
// ^^^^^^^^^^^^^^^^^^ return type changed from sub to sub_base<T,mat<T>>
;
add a comment |
The problem is, comparer_el
with rT=sub
is a better choise than the substitution+cast from sub
to sub_base<rT1,rT2>
. Deduction does not implicitly cast (except putting additional c/v qualifiers)... For a much better description, read this answer.
So, one solution is not to use return type sub
within getSub()
but the base type sub_base<rT1,rT2>
. see here
important part:
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub_base<T,mat<T>> getSub() return sub();;
// ^^^^^^^^^^^^^^^^^^ return type changed from sub to sub_base<T,mat<T>>
;
add a comment |
The problem is, comparer_el
with rT=sub
is a better choise than the substitution+cast from sub
to sub_base<rT1,rT2>
. Deduction does not implicitly cast (except putting additional c/v qualifiers)... For a much better description, read this answer.
So, one solution is not to use return type sub
within getSub()
but the base type sub_base<rT1,rT2>
. see here
important part:
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub_base<T,mat<T>> getSub() return sub();;
// ^^^^^^^^^^^^^^^^^^ return type changed from sub to sub_base<T,mat<T>>
;
The problem is, comparer_el
with rT=sub
is a better choise than the substitution+cast from sub
to sub_base<rT1,rT2>
. Deduction does not implicitly cast (except putting additional c/v qualifiers)... For a much better description, read this answer.
So, one solution is not to use return type sub
within getSub()
but the base type sub_base<rT1,rT2>
. see here
important part:
template <typename T>
class mat
class sub : public sub_base<T,mat<T>>
public:
sub(): sub_base<T,mat<T>>() ;
;
public:
int mb;
sub_base<T,mat<T>> getSub() return sub();;
// ^^^^^^^^^^^^^^^^^^ return type changed from sub to sub_base<T,mat<T>>
;
answered Nov 13 '18 at 16:27
user1810087user1810087
2,60312450
2,60312450
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%2f53284069%2fhow-to-specialize-templated-operator-overloads%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
@user1810087 I've edited the question, needed to call
getSub()
on comparison types.– joaocandre
Nov 13 '18 at 15:30
now it does compile :) BTW, i did not downvote your question... counter +1, because the question is interesting...
– user1810087
Nov 13 '18 at 15:36
Cannot put it into good words right now, but the problem is,
comparer_el
with the second parameter beeing substituted fromsub
totypename rT2
is a better choise as the substitution+cast fromsub
tosub_base<rT1,rT2>
. Substitution does not implicitly cast... So, one solution is not to use return typesub
withgetSub()
but the base typesub_base<rT1,rT2>
. see here, only change line 22– user1810087
Nov 13 '18 at 15:50
Also, return type
sub_base<rT1,rT2>
should be prefered as classsub
is nested and only known inside class mat...– user1810087
Nov 13 '18 at 15:59
Fair enough, I think I've understood the problem. The whole reason I nested class
sub
was to simplify the syntax and avoid trailing template arguments (the actual code is quite cluttered and hard to "read" as it is) - would a templated typedef work in this case?– joaocandre
Nov 13 '18 at 16:04