【发布时间】:2012-06-16 16:48:11
【问题描述】:
在下面的代码中,我试图用它作为参数的任何参数调用仿函数,“whatever”是一组有限的选项(这里的两个不是我的代码中唯一的选项)。
#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 中运行良好。不幸的是,它没有叮当声。错误信息是:
调用'call'没有匹配的函数
候选模板被忽略:替换失败 [with Callable = Test]:没有匹配的函数 调用“测试”类型的对象
所以它忽略了使用智能指针的候选者。好的。但它似乎并没有继续考虑可以正常工作的继承调用。
问题:我该如何解决这个问题?我怎样才能让 llvm 在这里做正确的事情?
【问题讨论】:
-
"How can I make llvm" nitpick:这里不涉及LLVM,只是clang。
-
是什么让您认为 clang 在这里有问题?您显然在返回类型上匹配,这是无效的。
-
为什么
call_with_pointer::call仍然使用shared_ptr<>作为第二个参数..? -
@David 不,我没有匹配任何东西,我指望 SFINAE 消除
call_with_shared::call并使用call_with_pointer::call。 -
@ildjarn 因为这是
call_with_shared的调用者传递的。它叫call_with_pointer而不是called_with_pointer;)