我正在寻找一种无需 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();
};
关于c++ - 在没有 SFINAE 的情况下启用类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32093730/