次のコードでは、パラメーターとして受け取るものは何でも、ファンクターを呼び出そうとしています。「何でも」は、オプションの限られたセットです (ここにある 2 つだけがコード内にあるわけではありません)。
#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;
}
このコードは VS とGCCで問題なく動作します。残念ながら、clang にはありません。エラーメッセージは次のとおりです。
'call' の呼び出しに一致する関数がありません
候補テンプレートは無視されました: 置換の失敗 [Callable = Test で]: タイプ 'Test' のオブジェクトへの呼び出しに一致する関数がありません
そのため、スマート ポインターを使用する候補は無視されます。良い。しかし、うまく機能する継承された呼び出しを検討し続けることはないようです。
質問: どうすればこれを回避できますか? ここでllvmに正しいことをさせるにはどうすればよいですか?