âmultiple overloadsâ using templated class with duplicate types
Clash Royale CLAN TAG#URR8PPP
up vote
8
down vote
favorite
I'm trying to write a class that takes two templated types. This class inherits from an interface. See the below code.
#include <iostream>
#include <string>
template <typename T>
class IObserver
public:
virtual void Next(const T& value) noexcept = 0;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<T2>
public:
void Next(const T1& value) noexcept override;
void Next(const T2& value) noexcept override;
;
int main()
// This is OK
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
// This fails to compile with "multiple overloads"
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
I'm having trouble when T1
is the same type as T2
. Obviously this means two Next
functions will be generated with the same type, which gives an error: multiple overloads of 'Next' instantiate to the same signature
.
What's an idiomatic way of fixing this? I'm not sure how to handle the case when T1=T2 since I'd only need one Next
function generated
Thanks!
c++ c++11 templates overloading
add a comment |Â
up vote
8
down vote
favorite
I'm trying to write a class that takes two templated types. This class inherits from an interface. See the below code.
#include <iostream>
#include <string>
template <typename T>
class IObserver
public:
virtual void Next(const T& value) noexcept = 0;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<T2>
public:
void Next(const T1& value) noexcept override;
void Next(const T2& value) noexcept override;
;
int main()
// This is OK
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
// This fails to compile with "multiple overloads"
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
I'm having trouble when T1
is the same type as T2
. Obviously this means two Next
functions will be generated with the same type, which gives an error: multiple overloads of 'Next' instantiate to the same signature
.
What's an idiomatic way of fixing this? I'm not sure how to handle the case when T1=T2 since I'd only need one Next
function generated
Thanks!
c++ c++11 templates overloading
1
It's not just the multiple overloads (which you can fix with someenable_if
magic) but you are also deriving twice from the same base class which is also not allowed. @VTT's answer fixes both issues.
â Alan Birtles
Sep 22 at 17:43
add a comment |Â
up vote
8
down vote
favorite
up vote
8
down vote
favorite
I'm trying to write a class that takes two templated types. This class inherits from an interface. See the below code.
#include <iostream>
#include <string>
template <typename T>
class IObserver
public:
virtual void Next(const T& value) noexcept = 0;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<T2>
public:
void Next(const T1& value) noexcept override;
void Next(const T2& value) noexcept override;
;
int main()
// This is OK
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
// This fails to compile with "multiple overloads"
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
I'm having trouble when T1
is the same type as T2
. Obviously this means two Next
functions will be generated with the same type, which gives an error: multiple overloads of 'Next' instantiate to the same signature
.
What's an idiomatic way of fixing this? I'm not sure how to handle the case when T1=T2 since I'd only need one Next
function generated
Thanks!
c++ c++11 templates overloading
I'm trying to write a class that takes two templated types. This class inherits from an interface. See the below code.
#include <iostream>
#include <string>
template <typename T>
class IObserver
public:
virtual void Next(const T& value) noexcept = 0;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<T2>
public:
void Next(const T1& value) noexcept override;
void Next(const T2& value) noexcept override;
;
int main()
// This is OK
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
// This fails to compile with "multiple overloads"
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
I'm having trouble when T1
is the same type as T2
. Obviously this means two Next
functions will be generated with the same type, which gives an error: multiple overloads of 'Next' instantiate to the same signature
.
What's an idiomatic way of fixing this? I'm not sure how to handle the case when T1=T2 since I'd only need one Next
function generated
Thanks!
c++ c++11 templates overloading
c++ c++11 templates overloading
edited Sep 22 at 16:42
asked Sep 22 at 16:36
Sam P
1,418824
1,418824
1
It's not just the multiple overloads (which you can fix with someenable_if
magic) but you are also deriving twice from the same base class which is also not allowed. @VTT's answer fixes both issues.
â Alan Birtles
Sep 22 at 17:43
add a comment |Â
1
It's not just the multiple overloads (which you can fix with someenable_if
magic) but you are also deriving twice from the same base class which is also not allowed. @VTT's answer fixes both issues.
â Alan Birtles
Sep 22 at 17:43
1
1
It's not just the multiple overloads (which you can fix with some
enable_if
magic) but you are also deriving twice from the same base class which is also not allowed. @VTT's answer fixes both issues.â Alan Birtles
Sep 22 at 17:43
It's not just the multiple overloads (which you can fix with some
enable_if
magic) but you are also deriving twice from the same base class which is also not allowed. @VTT's answer fixes both issues.â Alan Birtles
Sep 22 at 17:43
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
14
down vote
accepted
How about a specialization:
template <typename T>
class BinaryObserver<T, T> : public IObserver<T>
public:
void Next(const T & value) noexcept override;
;
Exactly what I needed, thank you!
â Sam P
Sep 24 at 17:36
add a comment |Â
up vote
0
down vote
You have another issue in your program:
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
Which one of the Next
you expect the compiler would choose in case you succeed?
In the VIT's answer you will have only a sigle Next
implemented in specification and calling it twice will do something different.
So, the best solution is to have different IObserver
classes with different function names to overload, i.e
class BinaryObserver : public IObserver<T1>, public IObserver1<T2>
...
mc2.Next(0);
mc2.Next1(0);
Another possibility is to put one of T
s in another container. I used Shell struct in this example:
template
struct Shell
T t;
Shell(T t): t(t)
operator T() const return t;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<Shell<T2>>
public:
void Next(const T1& value) noexcept overrideT1 t = value;;
void Next(const Shell<T2>& value) noexcept overrideT2 t = value;;
;
...
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(Shell<int>(0));
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
14
down vote
accepted
How about a specialization:
template <typename T>
class BinaryObserver<T, T> : public IObserver<T>
public:
void Next(const T & value) noexcept override;
;
Exactly what I needed, thank you!
â Sam P
Sep 24 at 17:36
add a comment |Â
up vote
14
down vote
accepted
How about a specialization:
template <typename T>
class BinaryObserver<T, T> : public IObserver<T>
public:
void Next(const T & value) noexcept override;
;
Exactly what I needed, thank you!
â Sam P
Sep 24 at 17:36
add a comment |Â
up vote
14
down vote
accepted
up vote
14
down vote
accepted
How about a specialization:
template <typename T>
class BinaryObserver<T, T> : public IObserver<T>
public:
void Next(const T & value) noexcept override;
;
How about a specialization:
template <typename T>
class BinaryObserver<T, T> : public IObserver<T>
public:
void Next(const T & value) noexcept override;
;
answered Sep 22 at 16:43
VTT
21.8k32345
21.8k32345
Exactly what I needed, thank you!
â Sam P
Sep 24 at 17:36
add a comment |Â
Exactly what I needed, thank you!
â Sam P
Sep 24 at 17:36
Exactly what I needed, thank you!
â Sam P
Sep 24 at 17:36
Exactly what I needed, thank you!
â Sam P
Sep 24 at 17:36
add a comment |Â
up vote
0
down vote
You have another issue in your program:
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
Which one of the Next
you expect the compiler would choose in case you succeed?
In the VIT's answer you will have only a sigle Next
implemented in specification and calling it twice will do something different.
So, the best solution is to have different IObserver
classes with different function names to overload, i.e
class BinaryObserver : public IObserver<T1>, public IObserver1<T2>
...
mc2.Next(0);
mc2.Next1(0);
Another possibility is to put one of T
s in another container. I used Shell struct in this example:
template
struct Shell
T t;
Shell(T t): t(t)
operator T() const return t;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<Shell<T2>>
public:
void Next(const T1& value) noexcept overrideT1 t = value;;
void Next(const Shell<T2>& value) noexcept overrideT2 t = value;;
;
...
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(Shell<int>(0));
add a comment |Â
up vote
0
down vote
You have another issue in your program:
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
Which one of the Next
you expect the compiler would choose in case you succeed?
In the VIT's answer you will have only a sigle Next
implemented in specification and calling it twice will do something different.
So, the best solution is to have different IObserver
classes with different function names to overload, i.e
class BinaryObserver : public IObserver<T1>, public IObserver1<T2>
...
mc2.Next(0);
mc2.Next1(0);
Another possibility is to put one of T
s in another container. I used Shell struct in this example:
template
struct Shell
T t;
Shell(T t): t(t)
operator T() const return t;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<Shell<T2>>
public:
void Next(const T1& value) noexcept overrideT1 t = value;;
void Next(const Shell<T2>& value) noexcept overrideT2 t = value;;
;
...
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(Shell<int>(0));
add a comment |Â
up vote
0
down vote
up vote
0
down vote
You have another issue in your program:
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
Which one of the Next
you expect the compiler would choose in case you succeed?
In the VIT's answer you will have only a sigle Next
implemented in specification and calling it twice will do something different.
So, the best solution is to have different IObserver
classes with different function names to overload, i.e
class BinaryObserver : public IObserver<T1>, public IObserver1<T2>
...
mc2.Next(0);
mc2.Next1(0);
Another possibility is to put one of T
s in another container. I used Shell struct in this example:
template
struct Shell
T t;
Shell(T t): t(t)
operator T() const return t;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<Shell<T2>>
public:
void Next(const T1& value) noexcept overrideT1 t = value;;
void Next(const Shell<T2>& value) noexcept overrideT2 t = value;;
;
...
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(Shell<int>(0));
You have another issue in your program:
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);
Which one of the Next
you expect the compiler would choose in case you succeed?
In the VIT's answer you will have only a sigle Next
implemented in specification and calling it twice will do something different.
So, the best solution is to have different IObserver
classes with different function names to overload, i.e
class BinaryObserver : public IObserver<T1>, public IObserver1<T2>
...
mc2.Next(0);
mc2.Next1(0);
Another possibility is to put one of T
s in another container. I used Shell struct in this example:
template
struct Shell
T t;
Shell(T t): t(t)
operator T() const return t;
;
template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<Shell<T2>>
public:
void Next(const T1& value) noexcept overrideT1 t = value;;
void Next(const Shell<T2>& value) noexcept overrideT2 t = value;;
;
...
BinaryObserver<int, float> mc1;
mc1.Next(0);
mc1.Next(0.0f);
BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(Shell<int>(0));
answered Sep 22 at 19:48
Serge
2,6902912
2,6902912
add a comment |Â
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52458675%2fmultiple-overloads-using-templated-class-with-duplicate-types%23new-answer', 'question_page');
);
Post as a guest
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
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
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
1
It's not just the multiple overloads (which you can fix with some
enable_if
magic) but you are also deriving twice from the same base class which is also not allowed. @VTT's answer fixes both issues.â Alan Birtles
Sep 22 at 17:43