At the moment, I have the below working code where using class X
, I provide a generic interface for multiple classes - I only expect a static f
function to be present, but neither do I fix the return type nor the parameters:
#include <iostream>
#include <type_traits>
class A {
public:
static void f()
{
std::cout << "A::f()" << std::endl;
}
};
class B {
public:
static size_t f(std::string const& s_)
{
std::cout << "B::f()" << std::endl;
return s_.size();
}
};
class C {
};
template <typename T>
class X {
public:
static
void
f(...)
{
std::cout << "Operation not supported!" << std::endl;
}
template <typename... Args>
static
std::result_of_t<decltype(&T::f)(Args...)>
f(Args&&... args_)
{
return T::f(std::forward<Args>(args_)...);
}
};
int main()
{
X<A>::f(); // Compiles, but unexpected overload!
auto const x = X<B>::f("Hello"); // Works just fine
std::cout << x << std::endl;
// X<C>::f(); // Does NOT compile!
return 0;
}
However, I've got multiple problems with it (as marked above in the comments):
If I allow the function to be not present and uncomment the line using
C
as a template parameter, the code does not compile, it still expectsC
to have a functionf
:In instantiation of ‘class X<C>’: required from here error: ‘f’ is not a member of ‘C’ std::result_of_t<decltype(&T::f)(Args...)>
Based on this, I expected the ellipsis parameter do the trick.
On the other hand, even if this worked, I would have another problem: though
A
providesf
, the overload with the ellipsis parameter is picked during overload resolution - where, of course,f
provided byA
is preferred.
(Used compiler: g++ (Ubuntu 8.1.0-5ubuntu1~16.04) 8.1.0; used standard: C++14.)
Any help solving the above problems (preferably both, at the same time) is welcomed.