我正在寻找一种方法来启用类方法而不使用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)。
答案 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();
};