我有课,Delegate
, 声明如下:
template<typename T> class Delegate;
template<typename R, typename... Args>
class Delegate<R(Args...)>
{ /*...*/ };
它可以被实例化为一个返回 ReturnType
的函数并且不接受参数作为 Delegate<ReturnType()>
.我遇到了一个问题,需要我专门研究类(class)' ()
这种情况下的运算符,但一直无法弄清楚如何在没有编译器错误的情况下强制编译器这样做。
我有以下功能:
template <typename R, typename... Args>
R Delegate<R(Args...)>::operator()(Args... args)
{ /*...*/ }
添加以下特化后,我收到一条错误消息 invalid use of incomplete type 'class Delegate<R()>'
:
template <typename R>
R Delegate<R()>::operator()()
{ /*...*/ }
但我不能简单地替换 Args...
与 void
或者,据我所知...这里的正确程序是什么,以及(如果这个问题适用并且您感觉特别有帮助)为什么?
最佳答案
您尝试使用 R Delegate<R()>::operator()()
特化甚至更多类模板的部分特化的成员函数由于§14.5.5.3 [temp.class.spec.mfunc]而失败:
1 The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization.
换句话说:
template <typename R>
R Delegate<R()>::operator()() { /**/ }
实际上是operator()
的特化您的主模板:
template <typename T>
class Delegate;
因为它是一个不完整的类型,所以你最终会遇到错误。可能的解决方法是:
选项#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 {}; }
};
选项#2
再使用一个专门的委托(delegate)类:
#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)...);
}
};
选项#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 {}; }
};
选项#4
从专门的类模板继承,可能利用 CRTP 习惯用法:
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...)>>;
};
关于c++ - [Args...] 为空的可变参数模板的部分模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26987216/