简体   繁体   English

为什么SFINAE不起作用?

[英]Why SFINAE doesn't work?

I want to check that whether the class has operator(). 我想检查该类是否具有operator()。 I tryied the following SFINAE. 我尝试了以下SFINAE。

#include <type_traits>  //for std::true_type/false_type
#include <utility>      //for std::declval

template <typename T, typename... A>
class has_call_operator {
private:
    template <typename U, typename... P>
    static auto check(U u, P... p) -> decltype(u(p...), std::true_type());
    static auto check(...) -> decltype(std::false_type());

public:
    using type
        = decltype(check(std::declval<T>(), std::declval<A>()...));
    static constexpr bool value = type::value;
};

At a glance, this is working correctlly. 乍一看,这是正确的。

#include <iostream>

struct test {
    void operator()(const int x) {}
};

int main()
{
    std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl;    //true
    return 0;
}

But, the abstract class was not worked correctly by it. 但是,抽象类无法正常工作。

#include <iostream>

struct test {
    void operator()(const int x) {}
    virtual void do_something() = 0;
};

int main()
{
    std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl;    //false
    return 0;
}

Why does not this code work? 为什么此代码不起作用? Also, could you make this code work? 另外,您可以使此代码正常工作吗?

You take U by value, so it requires also the construction of the type. 您可以按值来计算U ,因此也需要构造该类型。

Pass by const reference to fix that. 通过const引用来解决此问题。

You may look at is_detected and have something like: 您可能会看到is_detected并显示以下内容:

template <typename T, typename ...Ts>
using call_operator_type = decltype(std::declval<T>()(std::declval<Ts>()...));

template <typename T, typename ... Args>
using has_call_operator = is_detected<call_operator_type, T, Args...>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM