启用没有SFINAE的类方法

时间:2015-08-19 11:05:23

标签: c++ metaprogramming c++14

我正在寻找一种方法来启用类方法而不使用SFINAE ,可能是通过继承。

Im working on an improved version of std::function(带有table.gridview a:not(.btn), .table.gridview a:not(.btn) 的仿函数类)限定符(const,volatile)依赖于它的模板参数,例如:

  • operator()提供myfunctor<void()>
  • operator() ()提供myfunctor<void() const>
  • operator() () const提供myfunctor<void() volatile>

等等。

我不能使用SFINAE来解决这个问题的主要原因是,如果我使用SFINAE,则operator()需要模仿如下:

operator() () volatile

这意味着template<typename R = ReturnType> auto operator() (Args&&... args) -> std::enable_if_t<!Constant && !Volatile, R> { return (*_impl)(std::forward<Args>(args)...); } template<typename R = ReturnType> auto operator() (Args&&... args) const volatile -> std::enable_if_t<Constant && Volatile, R> { return (*_impl)(std::forward<Args>(args)...); } 不再可通过使用:

引用
operator()

我的第一个目的是使用超类,我可以继承&my_functor<void() const>::operator() 方法,但方法仍然需要访问包含虚拟类的operator()所包含的主实现,而且我不想将std::unique_ptr的引用传递给超类。

是否有其他或更好的方法来启用类方法而不进行模板化(不包括SFINAE)。

1 个答案:

答案 0 :(得分:4)

  

operator()不再可引用(...)

使用基于SFINAE的方法,仍然可以访问运算符,语法为:

&my::functor<void() const>::operator()<>
//                                    ↑↑
  

我的第一个目的是使用超类,我可以从中继承operator()方法,但是这些方法仍然需要访问std :: unique_ptr 所包含的主要实现

您可以使用CRTP惯用法,以便通过转码impl访问this

template <typename /*Fn*/, bool /*NonCopyable*/, bool /*Constant*/, bool /*Volatile*/>
class function;

template <typename CRTP>
struct call_operator;

template <typename ReturnType, typename... Args, bool NonCopyable>
struct call_operator<function<ReturnType(Args...), NonCopyable, true, false>>
{
    using func = function<ReturnType(Args...), NonCopyable, true, false>;

    ReturnType operator()(Args&&... args) const
    {
        return (*static_cast<const func*>(this)->_impl)(std::forward<Args>(args)...);
    }
};

template <typename ReturnType, typename... Args, bool NonCopyable>
struct call_operator<function<ReturnType(Args...), NonCopyable, true, true>>
{
    using func = function<ReturnType(Args...), NonCopyable, true, true>;

    ReturnType operator()(Args&&... args) const volatile
    {
        return (*static_cast<const volatile func*>(this)->_impl)(std::forward<Args>(args)...);
    }
};

template<typename ReturnType, typename... Args, bool NonCopyable, bool Constant, bool Volatile>
class function<ReturnType(Args...), NonCopyable, Constant, Volatile> : call_operator<function<ReturnType(Args...), NonCopyable, Constant, Volatile>>
{
    friend struct call_operator<function<ReturnType(Args...), NonCopyable, Constant, Volatile>>;

    std::unique_ptr<wrapper_impl<ReturnType(Args...)>> _impl;

public:
    function()
        : _impl(new fake_wrapper_impl<ReturnType(Args...)>()) { }

    using call_operator<function<ReturnType(Args...), NonCopyable, Constant, Volatile>>::operator();    
};

DEMO