SFINAE 不在 llvm/clang 上工作
SFINAE not working on llvm/clang
在下面的代码中,我试图调用一个函子,它采用任何参数,"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 中运行良好。不幸的是,它不会发出叮当声。错误消息是:
调用到"呼叫"没有匹配函数
忽略候选模板:替换失败 [可调用 = 测试]:没有匹配函数 调用类型为"测试"的对象
因此,它会忽略使用智能指针的候选项。好。但它似乎并没有继续考虑继承的调用,可以正常工作。
问题:我该如何解决此问题?我怎样才能让llvm在这里做正确的事情?
尝试以下操作:
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_pointer_2 {
// last resort: T*
template<class Callable>
static auto call(Callable &callable, const std::shared_ptr<T> ¶m) -> decltype(callable(param)) {
return callable(param);
}
};
template<class T>
struct call_with_shared : public call_with_pointer<T>, public call_with_pointer_2<T>{
using call_with_pointer<T>::call;
using call_with_pointer_2<T>::call;
};
严格来说,clang 是正确的,因为 C++11 的 7.3.3p15(继承函数模板的 using 声明被忽略,因为它与派生类的成员函数模板具有相同的名称和参数)。尽管很明显,该段没有考虑这些不冲突的声明是有缺陷的。
您可以通过使用类似 typename YieldFirstType<std::shared_ptr<T>, Callable>::type
的内容作为其中一个模板中的第二个参数类型来解决此问题。
相关文章:
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 检查工作正常的 CXX 编译器:/cygdrive/c/cygwin64/bin/clang++ -- 已损坏
- C++指向成员的指针的类内初始化会使 MSVC 失败(但 GCC/Clang 工作)
- 在 GCC 中工作的外行构造函数模板在 Clang 中失败
- GCC 和 clang 抛出"no matching function call"但 msvc (cl) 按预期编译和工作
- 在 gcc 上自己的元组实现段错误,同时在 clang 中工作
- dynamic_cast 在 clang 上无法跨模块边界工作
- 继承默认构造函数在 gcc 中失败并在 clang 中工作,哪个有错误?
- 构造函数上的SFINAE在VC2017中工作,但在clang / gcc中不起作用
- 无限递归模板实例化使用clang时GCC工作正常
- "Typedef redefinition with different types" Clang中关于工作MSVC代码的错误
- 变量args SFINAE默认构造函数在clang中工作,但在Visual Studio 2015中失败
- Clang+VS2013:包含c++标头时出错(vs2012:正在工作)
- SFINAE 不在 llvm/clang 上工作
- cpp 模板<>使用 clang 格式 3.6 的间距无法按预期工作
- 对于Clang和Codegen的MSVC 2015,我如何让ast dump工作
- Clang 无法在 std::experimental::optional(可选)中正常工作
- 派生类的特化std::hash可以在gcc中工作,而不是在clang中
- 带有inttype的枚举类的Printf不能在clang中工作
- 如何让c++ 0x / c++ 11风格的基于范围的for循环与clang一起工作