Reputation: 139
I'm just getting started with Object Oriented Programming. I'm trying to access member function of two different classes within a template function. I have restricted access to member functions based on boolean flag isAggregateElement
. For some reason, Compiler throws error stating that there is no such member function.
class descriptor{
public:
int getName(){
return -5;
}
};
class aggregate{
public:
int getDescription() {
return 234;
}
int getUnit(){
return 1;
}
};
template <typename T>
void buildObjectInfo(const T& classMemberType, const bool& isDataInterface){
T baseTypeElement = classMemberType;
bool isAggregateElement = !isDataInterface;
if(isAggregateElement){
cout<<baseTypeElement.getUnit()<<endl;
} else {
cout<<baseTypeElement.getName()<<endl; // Error gets resolved if I remove the else construct
}
}
int main()
{
aggregate a;
descriptor d;
buildObjectInfo<aggregate>(a,false);
return 0;
}
What should I do to access getUnit() without deleting boolean condition (or) removing else construct in the template function ?
Upvotes: 0
Views: 52
Reputation: 122458
Both branches must be valid. Suppose you call buildObjectInfo(d,false)
, what should happen then?
You can use constexpr if to discard the false branch.
Note that the getters should be const methods. The template argument can be deduced from the function parameter and you do not need the bool
:
#include <iostream>
#include <type_traits>
struct descriptor{
int getName() const { return -5; }
};
struct aggregate{
int getDescription() const { return 234; }
int getUnit() const { return 1; }
};
template <typename T>
void buildObjectInfo(const T& t){
if constexpr(std::is_same_v<aggregate,T>) {
std::cout << t.getUnit() << '\n';
} else {
std::cout << t.getName() << '\n';
}
}
int main() {
aggregate a;
descriptor d;
buildObjectInfo(a);
buildObjectInfo(d);
}
However, for only 2 different types an overloaded function is much simpler:
#include <iostream>
struct descriptor{
int getName() const { return -5; }
};
struct aggregate{
int getDescription() const { return 234; }
int getUnit() const { return 1; }
};
void buildObjectInfo(const aggregate& t) {
std::cout << t.getUnit() << '\n';
}
void buildObjectInfo(const descriptor& t) {
std::cout << t.getName() << '\n';
}
int main() {
aggregate a;
descriptor d;
buildObjectInfo(a);
buildObjectInfo(d);
}
Upvotes: 1