4

I think I understand by now why partial function templates are considered confusing and unnecessary, and are thus not allowed by the C++ standard. I would however appreciate some help with re-phrasing the following function w/o partial specialization. FWIW, the function is a member of a non-specialized class:

template <typename IMPL, typename RET>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

template <typename IMPL>
void call <IMPL, void_t> (functor <IMPL> func, 
                          IMPL * impl) 
{ 
  func.call (impl);
}

The problem here is that I can't overload on the function's return type. Also, the typename I want to specialize on is not used as function parameter - another reason why overloading does not help. Yes, I could introduce a dummy parameter, to force overloading, but that is ugly, isn't it?

Finally, why the heck isn't 'void' a type in C++? That would make things so much more consistent... But I am probably missing the complete picture...

4

5 回答 5

7

我相信,首先,如果你有一个返回 void 的函数,那么它对于returnvoid 表达式是完全合法的——例如调用另一个返回 void 的函数,其次,void 它是C++ 中的完整类型,你可以将它传递给尽可能多的模板。

于 2011-08-11T21:06:56.380 回答
2

如果你的functor模板类已经有一个 RET 的 typedef,你可以这样做:

template <typename IMPL>
typename functor<IMPL>::RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

并且不为超载而烦恼。另外,您使用的编译器是什么?所有符合标准的编译器都允许您voidvoid函数返回函数的结果。

于 2011-08-11T21:05:36.037 回答
2

第一的,

template <typename IMPL, typename RET>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

真的应该

template <typename RET, typename IMPL>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

(我反转RETIMPL在模板参数列表中)以便您可以调用函数

call<int>(f, impl);

而不必打字

call<impl_type, int>(f, impl);

确实,编译器无法推断RET,因此您必须自己提供。

其次,您不需要重载 for void,因为返回void表达式是可以的。如果需要,可以添加重载:

template <typename IMPL>
void call(functor<IMPL> func, IMPL* impl)

call(f, impl)在调用此重载时使用。

如果您有权访问 C++0x,请考虑使用decltype.

于 2011-08-11T21:21:39.090 回答
2

函数部分特化的一般解决方案包括使用具有相同模板参数的辅助类模板,以及具有与函数相同参数的单个方法。然后可以对模板类进行部分特化。

但是,在您的情况下,我认为您应该能够将其void用作您的返回类型,正如其他答案所指出的那样。

于 2011-08-11T21:12:32.560 回答
1

您可以通过使用函数重载来做到这一点:

template <typename IMPL, typename RET>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

template <typename IMPL>
void call (functor <void_t> func, void_t * impl) 
{ 
  func.call (impl);
}

此外,void是 C++ 中的一种类型;是什么让你认为它不是?

于 2011-08-11T21:06:18.050 回答