Reputation: 73
Assuming I have 2 overloaded methods in a class shown below Please ignore the need for such a weird overloading of methods it is something I came across recently
class A{
public:
//Lets call this method 1
int GetVal(bool isCondition) const
{
//do something and return val
}
//Lets call this method 2
template<typename T>
int GetVal(T expression)
{
//do something using expression
//and return val
}
};
int main()
{
A obj;
int val = obj.GetVal(false) << std::endl; //I want to invoke method 1
}
In the main()
function, I want to invoke method1 and not method2.
How can I achieve this?
Thanks for reading
Upvotes: 3
Views: 73
Reputation: 66200
In the main() function, I want to invoke method1 and not method2. How can I achieve this? Thanks for reading
And it's exactly what you get calling
obj.GetVal(false)
because false
is a bool
so it's an exact match for the not-template method. And when a call matches with a template method and a not template method, the not-template method (in case of exact match) is preferred.
The real problem is: how to invoke the method2 calling it with the type (bool
) of the not template method (method 1) ?
The answer (a possible answer) is: add a template
calling it
obj.template GetVal(false)
The following is a full working example
#include <iostream>
struct A
{
//Lets call this method 1
int GetVal (bool)
{ return 1; }
//Lets call this method 2
template <typename T>
int GetVal (T)
{ return 2; }
};
int main ()
{
A obj;
std::cout << obj.GetVal(false) << std::endl; // print 1
std::cout << obj.template GetVal(false) << std::endl; // print 2
}
-- EDIT --
Given that the OP precise that method 1 is const
(and method 2 isn't), method 2 become the better match.
The problem can be solved modifying A
as in Jarod42's answer (adding a not-const not-template method that call the const method or SFINAE disabling the template method 2 when T
is bool
) or as in Wanderer's answer (making const
also method 2).
But if you don't wont (or if you can't) modify the class A
, you can simply use static_assert()
directly in main()
std::cout << static_cast<A const &>(obj).GetVal(false) << std::endl;
Upvotes: 3
Reputation: 329
I know only 2 choices
Use all overloads as const
//Lets call this method 1
int GetVal(bool isCondition) const
{ /*do something and return val*/ }
//Lets call this method 2
template<typename T>
int GetVal(T expression) const
{ /*do something using expression and return val*/ }
or as non const
//Lets call this method 1
int GetVal(bool isCondition)
{ /*do something and return val*/ }
//Lets call this method 2
template<typename T>
int GetVal(T expression)
{ /*do something using expression and return val*/ }
Then Method 1 will be invoked
std::cout << obj.GetVal(false) << std::endl;
If you need Method 1 const use Jarod42 second example. It is wokring
template <typename T, std::enable_if_t<!std::is_same<bool, T>::value> = 0 >
int GetVal(T expression)
{ /*do something using expression and return val*/ }
Upvotes: 1
Reputation: 217135
You might add extra overload:
class A{
public:
// Lets call this method 1
int GetVal(bool isCondition) const { /* do something and return val */ }
int GetVal(bool b) { return static_cast<const A&>(*this).GetVal(); }
// Lets call this method 2
template<typename T>
int GetVal(T expression) { /* do something using expression and return val */ }}
};
Or use SFINAE for method2 to discard bool
parameter:
class A{
public:
// Lets call this method 1
int GetVal(bool isCondition) const { /* do something and return val */ }
// Lets call this method 2
template <typename T, std::enable_if_t<!std::is_same<bool, T>::value>, int> = 0>
int GetVal(T expression) { /* do something using expression and return val */ }}
};
Upvotes: 1