I am struggling to get the following code to work. This prints "No setAttr" which feels unexpected.
Basically I have a method in Parent class which creates and instance of a child class and checks whether given type has a particular method or not. This works when I make the method (setAttr()) public but doesn't for friend functions.
I understand that this may seem a bit strange, working with a bit of legacy code, the use case I am trying to solve it to hide a particular method (setAttr()) once created, this should only be accessible from the base class which will be responsible for generating instances of child classes
template <typename, typename = void_t<>>
struct has_set_attr_method {
static constexpr bool value = false;
};
template <typename T>
struct has_set_attr_method<T, void_t<decltype(std::declval<T>().setAttr())>> {
static constexpr bool value = true;
};
struct Parent {
public:
template<typename T>
static void create() {
auto obj = T::create();
if constexpr(has_set_attr_method<T>::value) {
cout << "has setAttr" << endl;
obj.toString();
} else {
cout << "no setAttr" << endl;
}
}
};
struct Child : public Parent {
public:
friend class Parent;
static auto create() {
return Child();
}
private:
void setAttr(int x) {
}
};
int main(int argc, char const *argv[]) {
Parent::create<Child>();
return 0;
}