C++ 可变模板的部分模板专门化,其中[Args…]为空

C++ 可变模板的部分模板专门化,其中[Args…]为空,c++,c++11,templates,variadic-templates,partial-specialization,C++,C++11,Templates,Variadic Templates,Partial Specialization,我有一个类,Delegate,声明如下: template<typename T> class Delegate; template<typename R, typename... Args> class Delegate<R(Args...)> { /*...*/ }; 添加以下专门化后,我得到一个错误,提示不完整类型“class Delegate”的使用无效: 模板 R委托::运算符()() { /*...*/ } 但就我所知,我也不能简单地用voi

我有一个类,
Delegate
,声明如下:

template<typename T> class Delegate;

template<typename R, typename... Args>
class Delegate<R(Args...)>
{ /*...*/ };
添加以下专门化后,我得到一个错误,提示
不完整类型“class Delegate”的使用无效

模板
R委托::运算符()()
{ /*...*/ }

但就我所知,我也不能简单地用
void
替换
Args…
。。。这里的正确过程是什么,以及(如果这个问题适用,并且您觉得非常有帮助)为什么?

您尝试使用
R Delegate::operator()
对类模板的部分专门化的成员函数进行更多专门化,但由于§14.5.5.3[temp.class.spec.mfunc]而失败:

1类模板部分专业化成员的模板参数列表应与类模板部分专业化的模板参数列表相匹配

换言之:

template <typename R>
R Delegate<R()>::operator()() { /**/ }
因为它是一个不完整的类型,所以最终会出现错误。可能的解决办法是:

选项1 专门化整个类并重新实现该类的所有成员:

template <typename T>
class Delegate;

template <typename R, typename... Args> // partial specialization for non-empty Args
class Delegate<R(Args...)>
{
    R operator()(Args...) { return {}; }
};

template <typename R> // partial specialization for empty Args
class Delegate<R()>
{
    R operator()() { return {}; }
};
模板
班级代表;
模板//非空参数的部分专门化
类委托
{
R运算符()(Args…{return{};}
};
模板//空参数的部分专门化
类委托
{
R运算符(){return{};}
};

选项2 使用另一个专用的委托类:

#include <utility>

template <typename T>
struct Impl;

template <typename R, typename... Args>
struct Impl<R(Args...)>
{
    static R call(Args&&...) { return {}; }
};

template <typename R>
struct Impl<R()>
{
    static R call() { return {}; }
};

template <typename T>
class Delegate;

template <typename R, typename... Args>
class Delegate<R(Args...)>
{
    R operator()(Args... args)
    {
        return Impl<R(Args...)>::call(std::forward<Args>(args)...);
    }
};
#包括
模板
结构Impl;
模板
结构Impl
{
静态R调用(Args&&…{return{};}
};
模板
结构Impl
{
静态R调用(){return{};}
};
模板
班级代表;
模板
类委托
{
R运算符()(Args…Args)
{
返回Impl::call(std::forward

选项3 使用一些丑陋的SFINAE:

#include <type_traits>

template <typename T>
class Delegate;

template <typename R, typename... Args>
class Delegate<R(Args...)>
{
    template <typename T = R>
    typename std::enable_if<sizeof...(Args) != 0 && std::is_same<T,R>{}, R>::type
    operator()(Args...) { return {}; }

    template <typename T = R>
    typename std::enable_if<sizeof...(Args) == 0 && std::is_same<T,R>{}, R>::type
    operator()() { return {}; }
};
#包括
模板
班级代表;
模板
类委托
{
模板
typename std::enable_if::type
运算符()(Args…{return{};}
模板
typename std::enable_if::type
运算符(){return{};}
};

选项4 从专用类模板继承,可能使用CRTP习惯用法:

模板
班级代表;
模板
结构基础;
模板
结构基
{
R运算符()(参数…)
{
委托*that=static_cast(此);
返回{};
}
};
模板
结构基
{
R运算符()()
{
委托*that=static_cast(此);
返回{};
}
};
模板
类委托:公共基
{
友元结构库;
};

@Manu343726两个字:部分订购。对不起,我没有注意到订购。我的错。在一个小手机上阅读答案:)@Manu343726没问题很好,@PiotrS。-谢谢你花这么多时间在这上面!
template <typename T>
class Delegate;

template <typename R, typename... Args> // partial specialization for non-empty Args
class Delegate<R(Args...)>
{
    R operator()(Args...) { return {}; }
};

template <typename R> // partial specialization for empty Args
class Delegate<R()>
{
    R operator()() { return {}; }
};
#include <utility>

template <typename T>
struct Impl;

template <typename R, typename... Args>
struct Impl<R(Args...)>
{
    static R call(Args&&...) { return {}; }
};

template <typename R>
struct Impl<R()>
{
    static R call() { return {}; }
};

template <typename T>
class Delegate;

template <typename R, typename... Args>
class Delegate<R(Args...)>
{
    R operator()(Args... args)
    {
        return Impl<R(Args...)>::call(std::forward<Args>(args)...);
    }
};
#include <type_traits>

template <typename T>
class Delegate;

template <typename R, typename... Args>
class Delegate<R(Args...)>
{
    template <typename T = R>
    typename std::enable_if<sizeof...(Args) != 0 && std::is_same<T,R>{}, R>::type
    operator()(Args...) { return {}; }

    template <typename T = R>
    typename std::enable_if<sizeof...(Args) == 0 && std::is_same<T,R>{}, R>::type
    operator()() { return {}; }
};
template <typename T>
class Delegate;

template <typename T>
struct Base;

template <typename R, typename... Args>
struct Base<Delegate<R(Args...)>>
{
    R operator()(Args...)
    {
        Delegate<R(Args...)>* that = static_cast<Delegate<R(Args...)>*>(this);
        return {};
    }
};

template <typename R>
struct Base<Delegate<R()>>
{
    R operator()()
    {
        Delegate<R()>* that = static_cast<Delegate<R()>*>(this);
        return {};
    }
};

template <typename R, typename... Args>
class Delegate<R(Args...)> : public Base<Delegate<R(Args...)>>
{
    friend struct Base<Delegate<R(Args...)>>;
};