C++:不允许 void 的部分函数专门化 - 替代解决方案?

发布于 2024-11-28 22:40:15 字数 581 浏览 1 评论 0原文

我想我现在明白为什么部分函数模板被认为是令人困惑和不必要的,因此不被 C++ 标准允许。不过,我希望能够帮助您重新表述以下没有部分专业化的函数。 FWIW,该函数是非专用类的成员:

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);
}

这里的问题是我无法重载函数的返回类型。另外,我想要专门研究的类型名不用作函数参数 - 重载无济于事的另一个原因。是的,我可以引入一个虚拟参数来强制重载,但这很丑陋,不是吗?

最后,为什么“void”不是 C++ 中的类型?这会让事情变得更加一致......但我可能错过了完整的图片......

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏天碎花小短裙 2024-12-05 22:40:15

我相信,首先,如果您有一个返回 void 的函数,那么返回 void 表达式是完全合法的 - 例如调用另一个返回 void 的函数,其次,返回 void C++ 中的完整类型,您可以根据需要将其传递给模板。

I believe that, firstly, if you have a function that returns void, then it's perfectly legitimate to return a void expression- such as the call of another function that returns void, and secondly, void is a full type in C++ and you can pass it to templates as much as you like.

蒲公英的约定 2024-12-05 22:40:15

首先,

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,所以你必须自己提供。

其次,您不需要重载 void,因为返回 void 表达式就可以了。如果需要,您可以添加一个重载:

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

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

如果您可以访问 C++0x,请考虑使用 decltype

First,

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

should really be

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

(I inversed RET and IMPL in the template argument list) so that you can call the function like

call<int>(f, impl);

instead of having to type

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

Indeed, the compiler cannot deduce RET, so you have to provide it yourself.

Second, you don't need to overload for void, since it is OK to return a void expression. If you want, you can add an overload:

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

and use call(f, impl) when calling this overload.

If you have access to C++0x, consider using decltype.

你曾走过我的故事 2024-12-05 22:40:15

如果您的函子模板类已经有 RET 的 typedef,您可以这样做:

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

而不用担心重载。另外,你用的编译器是什么?所有符合标准的编译器都允许您从 void 函数返回 void 函数的结果。

If your functor template class already has a typedef for RET, you can do this instead:

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

and not bother with the overload. Also, what is the compiler you are using? All standard-conformant compilers allow you to return the result of a void function from a void function.

℡Ms空城旧梦 2024-12-05 22:40:15

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

但是,就您而言,我认为您应该能够使用 void 作为返回类型,如其他答案所述。

The general solution for partial specialization of functions involves using a helper class template with the same template arguments, with a single method with the same arguments as your function. The template class can then be partially specialized.

In your case, however, I would think you should be able to use void as your return type, as noted by the other answers.

如日中天 2024-12-05 22:40:15

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

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++ 中的一种类型;是什么让你认为事实并非如此?

You could do this by using function overloading:

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);
}

Also, void is a type in C++; what makes you think that it isn't?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文