GCC can't differentiate between operator++() and operator++(int)
template <typename CRTP>
struct Pre {
CRTP & operator++();
};
template <typename CRTP>
struct Post {
CRTP operator++(int);
};
struct Derived
: Pre<Derived>
, Post<Derived>
{};
int main() {
Derived d;
d++;
++d;
}
I get these errors from GCC:
<source>: In function 'int main()':
<source>:18:10: error: request for member 'operator++' is ambiguous
d++;
^~
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
<source>:19:11: error: request for member 'operator++' is ambiguous
++d;
^
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
Pre-decrement and post-decrement operators cause similar errors. No such errors with Clang. Any ideas what could be wrong or how to work around this?
c++ operator-overloading multiple-inheritance ambiguous
|
show 5 more comments
template <typename CRTP>
struct Pre {
CRTP & operator++();
};
template <typename CRTP>
struct Post {
CRTP operator++(int);
};
struct Derived
: Pre<Derived>
, Post<Derived>
{};
int main() {
Derived d;
d++;
++d;
}
I get these errors from GCC:
<source>: In function 'int main()':
<source>:18:10: error: request for member 'operator++' is ambiguous
d++;
^~
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
<source>:19:11: error: request for member 'operator++' is ambiguous
++d;
^
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
Pre-decrement and post-decrement operators cause similar errors. No such errors with Clang. Any ideas what could be wrong or how to work around this?
c++ operator-overloading multiple-inheritance ambiguous
6
using Pre::operator++; using Post::operator++;
works, but I guess it defeats the purpose of your CRTP...
– Quentin
yesterday
1
fwiw also with supplying the implementation and also without crtp gcc reports the error
– user463035818
yesterday
3
@Quentin Puts using declaration in a helper templatePrePost : Pre, Post
– felix
yesterday
7
For me behavior of gcc seems to be correct. Invocation of functionoperator ++
should not compile because it is not clear to which function does the nameoperator ++
refer to.
– VTT
yesterday
2
It's not a defect in the sense that the language itself has an inconsistency that needs resolution. It's only a design choice with unfortunate consequences, a colloquial defect, if you were.
– StoryTeller
yesterday
|
show 5 more comments
template <typename CRTP>
struct Pre {
CRTP & operator++();
};
template <typename CRTP>
struct Post {
CRTP operator++(int);
};
struct Derived
: Pre<Derived>
, Post<Derived>
{};
int main() {
Derived d;
d++;
++d;
}
I get these errors from GCC:
<source>: In function 'int main()':
<source>:18:10: error: request for member 'operator++' is ambiguous
d++;
^~
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
<source>:19:11: error: request for member 'operator++' is ambiguous
++d;
^
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
Pre-decrement and post-decrement operators cause similar errors. No such errors with Clang. Any ideas what could be wrong or how to work around this?
c++ operator-overloading multiple-inheritance ambiguous
template <typename CRTP>
struct Pre {
CRTP & operator++();
};
template <typename CRTP>
struct Post {
CRTP operator++(int);
};
struct Derived
: Pre<Derived>
, Post<Derived>
{};
int main() {
Derived d;
d++;
++d;
}
I get these errors from GCC:
<source>: In function 'int main()':
<source>:18:10: error: request for member 'operator++' is ambiguous
d++;
^~
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
<source>:19:11: error: request for member 'operator++' is ambiguous
++d;
^
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
Pre-decrement and post-decrement operators cause similar errors. No such errors with Clang. Any ideas what could be wrong or how to work around this?
c++ operator-overloading multiple-inheritance ambiguous
c++ operator-overloading multiple-inheritance ambiguous
edited yesterday
jotik
asked yesterday
jotikjotik
8,58963792
8,58963792
6
using Pre::operator++; using Post::operator++;
works, but I guess it defeats the purpose of your CRTP...
– Quentin
yesterday
1
fwiw also with supplying the implementation and also without crtp gcc reports the error
– user463035818
yesterday
3
@Quentin Puts using declaration in a helper templatePrePost : Pre, Post
– felix
yesterday
7
For me behavior of gcc seems to be correct. Invocation of functionoperator ++
should not compile because it is not clear to which function does the nameoperator ++
refer to.
– VTT
yesterday
2
It's not a defect in the sense that the language itself has an inconsistency that needs resolution. It's only a design choice with unfortunate consequences, a colloquial defect, if you were.
– StoryTeller
yesterday
|
show 5 more comments
6
using Pre::operator++; using Post::operator++;
works, but I guess it defeats the purpose of your CRTP...
– Quentin
yesterday
1
fwiw also with supplying the implementation and also without crtp gcc reports the error
– user463035818
yesterday
3
@Quentin Puts using declaration in a helper templatePrePost : Pre, Post
– felix
yesterday
7
For me behavior of gcc seems to be correct. Invocation of functionoperator ++
should not compile because it is not clear to which function does the nameoperator ++
refer to.
– VTT
yesterday
2
It's not a defect in the sense that the language itself has an inconsistency that needs resolution. It's only a design choice with unfortunate consequences, a colloquial defect, if you were.
– StoryTeller
yesterday
6
6
using Pre::operator++; using Post::operator++;
works, but I guess it defeats the purpose of your CRTP...– Quentin
yesterday
using Pre::operator++; using Post::operator++;
works, but I guess it defeats the purpose of your CRTP...– Quentin
yesterday
1
1
fwiw also with supplying the implementation and also without crtp gcc reports the error
– user463035818
yesterday
fwiw also with supplying the implementation and also without crtp gcc reports the error
– user463035818
yesterday
3
3
@Quentin Puts using declaration in a helper template
PrePost : Pre, Post
– felix
yesterday
@Quentin Puts using declaration in a helper template
PrePost : Pre, Post
– felix
yesterday
7
7
For me behavior of gcc seems to be correct. Invocation of function
operator ++
should not compile because it is not clear to which function does the name operator ++
refer to.– VTT
yesterday
For me behavior of gcc seems to be correct. Invocation of function
operator ++
should not compile because it is not clear to which function does the name operator ++
refer to.– VTT
yesterday
2
2
It's not a defect in the sense that the language itself has an inconsistency that needs resolution. It's only a design choice with unfortunate consequences, a colloquial defect, if you were.
– StoryTeller
yesterday
It's not a defect in the sense that the language itself has an inconsistency that needs resolution. It's only a design choice with unfortunate consequences, a colloquial defect, if you were.
– StoryTeller
yesterday
|
show 5 more comments
1 Answer
1
active
oldest
votes
Name lookup must occur first. In this case for the name operator++
.
[basic.lookup] (emphasis mine)
1 The name lookup rules apply uniformly to all names (including
typedef-names ([dcl.typedef]), namespace-names ([basic.namespace]),
and class-names ([class.name])) wherever the grammar allows such names
in the context discussed by a particular rule. Name lookup associates
the use of a name with a declaration ([basic.def]) of that name. Name
lookup shall find an unambiguous declaration for the name (see
[class.member.lookup]). Name lookup may associate more than one
declaration with a name if it finds the name to be a function name;
the declarations are said to form a set of overloaded functions
([over.load]). Overload resolution ([over.match]) takes place after
name lookup has succeeded. The access rules (Clause [class.access])
are considered only once name lookup and function overload resolution
(if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded
are the attributes introduced by the name's declaration used further
in expression processing (Clause [expr]).
And only if the lookup is unambiguous, will overload resolution proceed. In this case, the name is found in the scope of two different classes, and so an ambiguity is present even prior to overload resolution.
[class.member.lookup]
8 If the name of an overloaded function is unambiguously found,
overloading resolution ([over.match]) also takes place before access
control. Ambiguities can often be resolved by qualifying a name with
its class name. [ Example:
struct A {
int f();
};
struct B {
int f();
};
struct C : A, B {
int f() { return A::f() + B::f(); }
};
— end example ]
The example pretty much summarizes the rather long lookup rules in the previous paragraphs of [class.member.lookup]. There is an ambiguity in your code. GCC is correct to report it.
As for working around this, people in comments already presented the ideas for a workaround. Add a helper CRTP class
template <class CRTP>
struct PrePost
: Pre<CRTP>
, Post<CRTP>
{
using Pre<CRTP>::operator++;
using Post<CRTP>::operator++;
};
struct Derived : PrePost<Derived> {};
The name is now found in the scope of a single class, and names both overloads. Lookup is successful, and overload resolution may proceed.
12
Fwiw, MS VS2015 (19.00.24215.1) complains about the ambiguity via IntelliNonsense, but then still compiles the code to success (with no warnings or errors) and executes the hoped-for members at run-time.
– WhozCraig
yesterday
4
@StoryTeller Indeed, for a "normal" methodf()
vs.f(int)
,clang++
complains about: "error: member 'f' found in multiple base classes of different types" and adds "note: member found by ambiguous name lookup". GCC is actually more consistent here.
– Arne Vogel
yesterday
3
Ok. So it appears that this is sort-of a defect in the language (thatd++
and++d
refer to the same operator/function name), which gcc faithfully implements, while clang and VS17 appear to implement what the user obviously intended (even w/o warning).
– Walter
yesterday
1
@Walter - Pretty much. Had we taken a path like, say, Python with regards to overloading, it'd had probably been easier to work with all around. Alas, something else was choesn.
– StoryTeller
yesterday
2
@PiotrNycz - Other than being called by a special syntax, overloaded operators are regular functions. As a matter of fact, they can also be called just like regular functions.d.operator++(0)
will cause this ambiguity, as shouldd++
, since the two are exactly equivalent.
– StoryTeller
yesterday
|
show 9 more comments
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%2f54091513%2fgcc-cant-differentiate-between-operator-and-operatorint%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
Name lookup must occur first. In this case for the name operator++
.
[basic.lookup] (emphasis mine)
1 The name lookup rules apply uniformly to all names (including
typedef-names ([dcl.typedef]), namespace-names ([basic.namespace]),
and class-names ([class.name])) wherever the grammar allows such names
in the context discussed by a particular rule. Name lookup associates
the use of a name with a declaration ([basic.def]) of that name. Name
lookup shall find an unambiguous declaration for the name (see
[class.member.lookup]). Name lookup may associate more than one
declaration with a name if it finds the name to be a function name;
the declarations are said to form a set of overloaded functions
([over.load]). Overload resolution ([over.match]) takes place after
name lookup has succeeded. The access rules (Clause [class.access])
are considered only once name lookup and function overload resolution
(if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded
are the attributes introduced by the name's declaration used further
in expression processing (Clause [expr]).
And only if the lookup is unambiguous, will overload resolution proceed. In this case, the name is found in the scope of two different classes, and so an ambiguity is present even prior to overload resolution.
[class.member.lookup]
8 If the name of an overloaded function is unambiguously found,
overloading resolution ([over.match]) also takes place before access
control. Ambiguities can often be resolved by qualifying a name with
its class name. [ Example:
struct A {
int f();
};
struct B {
int f();
};
struct C : A, B {
int f() { return A::f() + B::f(); }
};
— end example ]
The example pretty much summarizes the rather long lookup rules in the previous paragraphs of [class.member.lookup]. There is an ambiguity in your code. GCC is correct to report it.
As for working around this, people in comments already presented the ideas for a workaround. Add a helper CRTP class
template <class CRTP>
struct PrePost
: Pre<CRTP>
, Post<CRTP>
{
using Pre<CRTP>::operator++;
using Post<CRTP>::operator++;
};
struct Derived : PrePost<Derived> {};
The name is now found in the scope of a single class, and names both overloads. Lookup is successful, and overload resolution may proceed.
12
Fwiw, MS VS2015 (19.00.24215.1) complains about the ambiguity via IntelliNonsense, but then still compiles the code to success (with no warnings or errors) and executes the hoped-for members at run-time.
– WhozCraig
yesterday
4
@StoryTeller Indeed, for a "normal" methodf()
vs.f(int)
,clang++
complains about: "error: member 'f' found in multiple base classes of different types" and adds "note: member found by ambiguous name lookup". GCC is actually more consistent here.
– Arne Vogel
yesterday
3
Ok. So it appears that this is sort-of a defect in the language (thatd++
and++d
refer to the same operator/function name), which gcc faithfully implements, while clang and VS17 appear to implement what the user obviously intended (even w/o warning).
– Walter
yesterday
1
@Walter - Pretty much. Had we taken a path like, say, Python with regards to overloading, it'd had probably been easier to work with all around. Alas, something else was choesn.
– StoryTeller
yesterday
2
@PiotrNycz - Other than being called by a special syntax, overloaded operators are regular functions. As a matter of fact, they can also be called just like regular functions.d.operator++(0)
will cause this ambiguity, as shouldd++
, since the two are exactly equivalent.
– StoryTeller
yesterday
|
show 9 more comments
Name lookup must occur first. In this case for the name operator++
.
[basic.lookup] (emphasis mine)
1 The name lookup rules apply uniformly to all names (including
typedef-names ([dcl.typedef]), namespace-names ([basic.namespace]),
and class-names ([class.name])) wherever the grammar allows such names
in the context discussed by a particular rule. Name lookup associates
the use of a name with a declaration ([basic.def]) of that name. Name
lookup shall find an unambiguous declaration for the name (see
[class.member.lookup]). Name lookup may associate more than one
declaration with a name if it finds the name to be a function name;
the declarations are said to form a set of overloaded functions
([over.load]). Overload resolution ([over.match]) takes place after
name lookup has succeeded. The access rules (Clause [class.access])
are considered only once name lookup and function overload resolution
(if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded
are the attributes introduced by the name's declaration used further
in expression processing (Clause [expr]).
And only if the lookup is unambiguous, will overload resolution proceed. In this case, the name is found in the scope of two different classes, and so an ambiguity is present even prior to overload resolution.
[class.member.lookup]
8 If the name of an overloaded function is unambiguously found,
overloading resolution ([over.match]) also takes place before access
control. Ambiguities can often be resolved by qualifying a name with
its class name. [ Example:
struct A {
int f();
};
struct B {
int f();
};
struct C : A, B {
int f() { return A::f() + B::f(); }
};
— end example ]
The example pretty much summarizes the rather long lookup rules in the previous paragraphs of [class.member.lookup]. There is an ambiguity in your code. GCC is correct to report it.
As for working around this, people in comments already presented the ideas for a workaround. Add a helper CRTP class
template <class CRTP>
struct PrePost
: Pre<CRTP>
, Post<CRTP>
{
using Pre<CRTP>::operator++;
using Post<CRTP>::operator++;
};
struct Derived : PrePost<Derived> {};
The name is now found in the scope of a single class, and names both overloads. Lookup is successful, and overload resolution may proceed.
12
Fwiw, MS VS2015 (19.00.24215.1) complains about the ambiguity via IntelliNonsense, but then still compiles the code to success (with no warnings or errors) and executes the hoped-for members at run-time.
– WhozCraig
yesterday
4
@StoryTeller Indeed, for a "normal" methodf()
vs.f(int)
,clang++
complains about: "error: member 'f' found in multiple base classes of different types" and adds "note: member found by ambiguous name lookup". GCC is actually more consistent here.
– Arne Vogel
yesterday
3
Ok. So it appears that this is sort-of a defect in the language (thatd++
and++d
refer to the same operator/function name), which gcc faithfully implements, while clang and VS17 appear to implement what the user obviously intended (even w/o warning).
– Walter
yesterday
1
@Walter - Pretty much. Had we taken a path like, say, Python with regards to overloading, it'd had probably been easier to work with all around. Alas, something else was choesn.
– StoryTeller
yesterday
2
@PiotrNycz - Other than being called by a special syntax, overloaded operators are regular functions. As a matter of fact, they can also be called just like regular functions.d.operator++(0)
will cause this ambiguity, as shouldd++
, since the two are exactly equivalent.
– StoryTeller
yesterday
|
show 9 more comments
Name lookup must occur first. In this case for the name operator++
.
[basic.lookup] (emphasis mine)
1 The name lookup rules apply uniformly to all names (including
typedef-names ([dcl.typedef]), namespace-names ([basic.namespace]),
and class-names ([class.name])) wherever the grammar allows such names
in the context discussed by a particular rule. Name lookup associates
the use of a name with a declaration ([basic.def]) of that name. Name
lookup shall find an unambiguous declaration for the name (see
[class.member.lookup]). Name lookup may associate more than one
declaration with a name if it finds the name to be a function name;
the declarations are said to form a set of overloaded functions
([over.load]). Overload resolution ([over.match]) takes place after
name lookup has succeeded. The access rules (Clause [class.access])
are considered only once name lookup and function overload resolution
(if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded
are the attributes introduced by the name's declaration used further
in expression processing (Clause [expr]).
And only if the lookup is unambiguous, will overload resolution proceed. In this case, the name is found in the scope of two different classes, and so an ambiguity is present even prior to overload resolution.
[class.member.lookup]
8 If the name of an overloaded function is unambiguously found,
overloading resolution ([over.match]) also takes place before access
control. Ambiguities can often be resolved by qualifying a name with
its class name. [ Example:
struct A {
int f();
};
struct B {
int f();
};
struct C : A, B {
int f() { return A::f() + B::f(); }
};
— end example ]
The example pretty much summarizes the rather long lookup rules in the previous paragraphs of [class.member.lookup]. There is an ambiguity in your code. GCC is correct to report it.
As for working around this, people in comments already presented the ideas for a workaround. Add a helper CRTP class
template <class CRTP>
struct PrePost
: Pre<CRTP>
, Post<CRTP>
{
using Pre<CRTP>::operator++;
using Post<CRTP>::operator++;
};
struct Derived : PrePost<Derived> {};
The name is now found in the scope of a single class, and names both overloads. Lookup is successful, and overload resolution may proceed.
Name lookup must occur first. In this case for the name operator++
.
[basic.lookup] (emphasis mine)
1 The name lookup rules apply uniformly to all names (including
typedef-names ([dcl.typedef]), namespace-names ([basic.namespace]),
and class-names ([class.name])) wherever the grammar allows such names
in the context discussed by a particular rule. Name lookup associates
the use of a name with a declaration ([basic.def]) of that name. Name
lookup shall find an unambiguous declaration for the name (see
[class.member.lookup]). Name lookup may associate more than one
declaration with a name if it finds the name to be a function name;
the declarations are said to form a set of overloaded functions
([over.load]). Overload resolution ([over.match]) takes place after
name lookup has succeeded. The access rules (Clause [class.access])
are considered only once name lookup and function overload resolution
(if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded
are the attributes introduced by the name's declaration used further
in expression processing (Clause [expr]).
And only if the lookup is unambiguous, will overload resolution proceed. In this case, the name is found in the scope of two different classes, and so an ambiguity is present even prior to overload resolution.
[class.member.lookup]
8 If the name of an overloaded function is unambiguously found,
overloading resolution ([over.match]) also takes place before access
control. Ambiguities can often be resolved by qualifying a name with
its class name. [ Example:
struct A {
int f();
};
struct B {
int f();
};
struct C : A, B {
int f() { return A::f() + B::f(); }
};
— end example ]
The example pretty much summarizes the rather long lookup rules in the previous paragraphs of [class.member.lookup]. There is an ambiguity in your code. GCC is correct to report it.
As for working around this, people in comments already presented the ideas for a workaround. Add a helper CRTP class
template <class CRTP>
struct PrePost
: Pre<CRTP>
, Post<CRTP>
{
using Pre<CRTP>::operator++;
using Post<CRTP>::operator++;
};
struct Derived : PrePost<Derived> {};
The name is now found in the scope of a single class, and names both overloads. Lookup is successful, and overload resolution may proceed.
edited yesterday
answered yesterday
StoryTellerStoryTeller
94.4k12191254
94.4k12191254
12
Fwiw, MS VS2015 (19.00.24215.1) complains about the ambiguity via IntelliNonsense, but then still compiles the code to success (with no warnings or errors) and executes the hoped-for members at run-time.
– WhozCraig
yesterday
4
@StoryTeller Indeed, for a "normal" methodf()
vs.f(int)
,clang++
complains about: "error: member 'f' found in multiple base classes of different types" and adds "note: member found by ambiguous name lookup". GCC is actually more consistent here.
– Arne Vogel
yesterday
3
Ok. So it appears that this is sort-of a defect in the language (thatd++
and++d
refer to the same operator/function name), which gcc faithfully implements, while clang and VS17 appear to implement what the user obviously intended (even w/o warning).
– Walter
yesterday
1
@Walter - Pretty much. Had we taken a path like, say, Python with regards to overloading, it'd had probably been easier to work with all around. Alas, something else was choesn.
– StoryTeller
yesterday
2
@PiotrNycz - Other than being called by a special syntax, overloaded operators are regular functions. As a matter of fact, they can also be called just like regular functions.d.operator++(0)
will cause this ambiguity, as shouldd++
, since the two are exactly equivalent.
– StoryTeller
yesterday
|
show 9 more comments
12
Fwiw, MS VS2015 (19.00.24215.1) complains about the ambiguity via IntelliNonsense, but then still compiles the code to success (with no warnings or errors) and executes the hoped-for members at run-time.
– WhozCraig
yesterday
4
@StoryTeller Indeed, for a "normal" methodf()
vs.f(int)
,clang++
complains about: "error: member 'f' found in multiple base classes of different types" and adds "note: member found by ambiguous name lookup". GCC is actually more consistent here.
– Arne Vogel
yesterday
3
Ok. So it appears that this is sort-of a defect in the language (thatd++
and++d
refer to the same operator/function name), which gcc faithfully implements, while clang and VS17 appear to implement what the user obviously intended (even w/o warning).
– Walter
yesterday
1
@Walter - Pretty much. Had we taken a path like, say, Python with regards to overloading, it'd had probably been easier to work with all around. Alas, something else was choesn.
– StoryTeller
yesterday
2
@PiotrNycz - Other than being called by a special syntax, overloaded operators are regular functions. As a matter of fact, they can also be called just like regular functions.d.operator++(0)
will cause this ambiguity, as shouldd++
, since the two are exactly equivalent.
– StoryTeller
yesterday
12
12
Fwiw, MS VS2015 (19.00.24215.1) complains about the ambiguity via IntelliNonsense, but then still compiles the code to success (with no warnings or errors) and executes the hoped-for members at run-time.
– WhozCraig
yesterday
Fwiw, MS VS2015 (19.00.24215.1) complains about the ambiguity via IntelliNonsense, but then still compiles the code to success (with no warnings or errors) and executes the hoped-for members at run-time.
– WhozCraig
yesterday
4
4
@StoryTeller Indeed, for a "normal" method
f()
vs. f(int)
, clang++
complains about: "error: member 'f' found in multiple base classes of different types" and adds "note: member found by ambiguous name lookup". GCC is actually more consistent here.– Arne Vogel
yesterday
@StoryTeller Indeed, for a "normal" method
f()
vs. f(int)
, clang++
complains about: "error: member 'f' found in multiple base classes of different types" and adds "note: member found by ambiguous name lookup". GCC is actually more consistent here.– Arne Vogel
yesterday
3
3
Ok. So it appears that this is sort-of a defect in the language (that
d++
and ++d
refer to the same operator/function name), which gcc faithfully implements, while clang and VS17 appear to implement what the user obviously intended (even w/o warning).– Walter
yesterday
Ok. So it appears that this is sort-of a defect in the language (that
d++
and ++d
refer to the same operator/function name), which gcc faithfully implements, while clang and VS17 appear to implement what the user obviously intended (even w/o warning).– Walter
yesterday
1
1
@Walter - Pretty much. Had we taken a path like, say, Python with regards to overloading, it'd had probably been easier to work with all around. Alas, something else was choesn.
– StoryTeller
yesterday
@Walter - Pretty much. Had we taken a path like, say, Python with regards to overloading, it'd had probably been easier to work with all around. Alas, something else was choesn.
– StoryTeller
yesterday
2
2
@PiotrNycz - Other than being called by a special syntax, overloaded operators are regular functions. As a matter of fact, they can also be called just like regular functions.
d.operator++(0)
will cause this ambiguity, as should d++
, since the two are exactly equivalent.– StoryTeller
yesterday
@PiotrNycz - Other than being called by a special syntax, overloaded operators are regular functions. As a matter of fact, they can also be called just like regular functions.
d.operator++(0)
will cause this ambiguity, as should d++
, since the two are exactly equivalent.– StoryTeller
yesterday
|
show 9 more comments
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f54091513%2fgcc-cant-differentiate-between-operator-and-operatorint%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
6
using Pre::operator++; using Post::operator++;
works, but I guess it defeats the purpose of your CRTP...– Quentin
yesterday
1
fwiw also with supplying the implementation and also without crtp gcc reports the error
– user463035818
yesterday
3
@Quentin Puts using declaration in a helper template
PrePost : Pre, Post
– felix
yesterday
7
For me behavior of gcc seems to be correct. Invocation of function
operator ++
should not compile because it is not clear to which function does the nameoperator ++
refer to.– VTT
yesterday
2
It's not a defect in the sense that the language itself has an inconsistency that needs resolution. It's only a design choice with unfortunate consequences, a colloquial defect, if you were.
– StoryTeller
yesterday