在没有 SFINAE 的情况下启用 class 方法
Enable class methods without SFINAE
我正在寻找一种在没有 SFINAE 的情况下启用 class 方法 的方法,可能是通过继承。
Im working on an improved version of std::function(函子class with 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()
我的第一个意图是使用 superclasses,我可以从中继承 operator()
方法,但这些方法仍然需要访问包含在 [=22 中的主要实现=] 它包含一个虚拟 class,我不想将 std::unique_ptr
的引用传递给超级 class。
是否有另一种或更好的方法来启用 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 习惯用法,这样 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();
};
我正在寻找一种在没有 SFINAE 的情况下启用 class 方法 的方法,可能是通过继承。
Im working on an improved version of std::function(函子class with 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()
我的第一个意图是使用 superclasses,我可以从中继承 operator()
方法,但这些方法仍然需要访问包含在 [=22 中的主要实现=] 它包含一个虚拟 class,我不想将 std::unique_ptr
的引用传递给超级 class。
是否有另一种或更好的方法来启用 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 习惯用法,这样 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();
};