c++ - 在没有 SFINAE 的情况下启用类方法

标签 c++ metaprogramming c++14

我正在寻找一种无需 SFINAE 即可启用类方法的方法,可能是通过继承。

Im working on an improved version of std::function (带有 operator() 的仿函数类)哪个限定符(const,volatile)取决于它的模板参数,例如:

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

等等。

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

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() 的父类(super class)来自的方法,但这些方法仍然需要访问 std::unique_ptr 包含的主要实现。它拥有一个虚拟类,我不想传递 std::unique_ptr 的引用到父类(super class)。

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

最佳答案

operator() isn't referenceable anymore (...)

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

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

My first intention was to use superclasses where i can inherit the operator() methods from but the methods still need to have access to the main implementation which is contained by a std::unique_ptr

您可以使用 CRTP 习惯用法,以便通过向下转换 this 访问 impl:

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

关于c++ - 在没有 SFINAE 的情况下启用类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32093730/

相关文章:

c++ - 是否可以为 std::array 类型添加自己的构造函数?

c++ - 如何将 child 添加到 BST

c++ - 自定义快捷方式的上下文菜单

c++ - 为什么起源进程在 Qt-app 中以僵尸启动。 Linux

c++ - 在模板类中时枚举中的整数溢出

javascript - 是否有 Julia 的 JavaScript 和 TypeScript 元编程和宏的等价物?

c++ - 替换模板上的虚函数

c++ - 递归计算变量模板值

c++ - 获取通过环境变量访问的文件的位置

c++ - 为什么 map 上的 std::for_each 会调用复制构造函数?