SFINAE不适用于llvm / clang [英] SFINAE not working on llvm/clang

查看:100
本文介绍了SFINAE不适用于llvm / clang的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,我试图以任何参数作为参数来调用仿函数,无论如何是一组有限的选项(这两个不是我的代码中唯一的)。

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> &param) -> 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> &param) -> 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 。不幸的是,它并不在lang。错误消息是:

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'

候选模板被忽略:替换失败[with Callable = Test]:
没有匹配函数调用类型为'Test'的对象

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.

问题:我该如何解决?

推荐答案

尝试以下操作:

template<class T>
struct call_with_pointer {
    // last resort: T*
    template<class Callable>
    static auto call(Callable &callable, const std::shared_ptr<T> &param) -> 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> &param) -> 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;
};

这篇关于SFINAE不适用于llvm / clang的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆