In the following code I'm trying to call a functor with whatever it takes as its parameters, "whatever" being a limited set of options (the two here are not the only ones in my code).
#include <memory>
#include <iostream>
template<class T>
struct call_with_pointer {
// last resort: T*
template<class Callable>
static auto call(Callable &callable, const std::shared_ptr<T> ¶m) -> decltype(callable(param.get())) {
return callable(param.get());
}
};
template<class T>
struct call_with_shared : public call_with_pointer<T> {
// best: call with shared_ptr<T>.
// SFINA
// error: Candidate template ignored: substitution failure [with Callable = Test]: no matching function for call to object of type 'Test'
template<class Callable>
static auto call(Callable &callable, const std::shared_ptr<T> ¶m) -> decltype(callable(param)) {
return callable(param);
}
using call_with_pointer<T>::call;
};
class Test {
public:
bool operator () (int * x) {
return *x == 42;
}
};
int main ()
{
Test t;
auto i = std::make_shared<int>(4);
auto x = call_with_shared<int>::call(t, i); // No matching function for call to 'call'
return 0;
}
This code works just fine in VS and GCC. Unfortunately it does not in clang. The error message is:
No matching function for call to 'call'
Candidate template ignored: substitution failure [with Callable = Test]: no matching function for call to object of type 'Test'
So it ignores the candidate that uses the smart pointer. Good. But it does not seem to continue with considering the inherited call that would work just fine.
Question: How can I work around this? How can I make llvm do the right thing here?