The code below fails with the error:
error C2923: 'std::is_same_v': 'A::B' is not a valid template type argument for parameter '<unnamed-symbol>'
#include <iostream>
//Primary template
template<typename T> struct ClassOf {
};
// Partial specialisation
template<typename Return, typename Class>
struct ClassOf<Return(Class::*)> {
using type = Class;};
//An alias
template< typename T> using ClassOf_t = typename ClassOf<T>::type;
struct A {
struct B {
void methodB () {}
};
B* myPtr;
// Rename the function to BB() and do this as well on L29 and the code will compile
B* B() { return myPtr; }
};
struct C {
template <typename T>
T* getClient() {
if constexpr (std::is_same_v<A::B,T>) {
return myA.B();
}
}
A myA;
};
int main()
{
auto fn = &A::B::methodB;
ClassOf_t<decltype(fn)> a;
a.methodB();
C c;
auto res = c.getClient<ClassOf_t<decltype(fn)>>();
res->methodB();
return 0;
}
However, if I rename the function on L22 to BB():
B* BB() { return myPtr; }
and do this as well on L29:
return myA.BB();
Then the code compiles.
Is there any way I can make this compile without changing anything in struct A?
I would not myself choose member function names that could cause conflict, but I am working with GRPC and those generated client classes look like struct A above.
For example, the link below shows this for the Stub class (on L164) which has an async nested class (L208) and an async() member function (L224):
https://github.com/SafetyCulture/s12-proto/blob/master/protobuf/protoc-gen-cruxclient/generated/routeguide/v1/route_guide.grpc.pb.h