本文介绍了如何对互斥的非成员函数模板使用enable_if?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写非成员运算符函数模板,如:

I'm trying to write non-member operator function templates like:

#include <utility>

template < typename T, unsigned L >
class MyType;

template < typename T, typename U, unsigned L >
auto  operator ==( MyType<T,L> const &l, MyType<U,L> const &r )
 -> decltype( std::declval<T>() == std::declval<U>() )
{ /*...*/ }

但是当我尝试处理 l r 有不同的长度:

But when I try to handle when l and r have different lengths:

template < typename T, unsigned Lt, typename U, unsigned Lu, class Enable = typename std::enable_if<(Lt < Lu)>::type >
auto  operator ==( MyType<T,Lt> const &l, MyType<U,Lu> const &r )
 -> decltype( std::declval<T>() == std::declval<U>() )
{ /*...*/ }

template < typename T, unsigned Lt, typename U, unsigned Lu, class Enable = typename std::enable_if<(Lt > Lu)>::type >
auto  operator ==( MyType<T,Lt> const &l, MyType<U,Lu> const &r )
 -> decltype( std::declval<T>() == std::declval<U>() )
{ /*...*/ }

我得到不明确的错误。我尝试了像:

I get ambiguity errors. I tried something like:

template < typename T, unsigned Lt, typename U, unsigned Lu, bool B = (Lt < Lu), class Enable = typename std::enable_if<B>::type >
auto  operator ==( MyType<T,Lt> const &l, MyType<U,Lu> const &r )
 -> decltype( std::declval<T>() == std::declval<U>() )
{ /*...*/ }

template < typename T, unsigned Lt, typename U, unsigned Lu, bool B = (Lt > Lu), class Enable = typename std::enable_if<B>::type >
auto  operator ==( MyType<T,Lt> const &l, MyType<U,Lu> const &r )
 -> decltype( std::declval<T>() == std::declval<U>() )
{ /*...*/ }

我已经阅读(这里在SO)解决这样的成员函数模板的问题。 (有时,受访者将成员函数更改为成员函数模板以启用此功能。)但是错误不会改变我。我必须切换到 enable_if 到返回类型吗?

which I've read (here on S.O.) to solve problems like this for member function templates. (Sometimes, the respondents changed a member function to a member function template to enable this.) But the errors don't change for me. Do I have to switch to putting enable_if into the return type?

哦,返回类型表达式应该是当两个元素类型无法比较时,排除此运算符。它会工作吗?是否兼容 enable_if

Oh, the return type expression is supposed to exclude this operator when the two element types can't be compared. Will it actually work? Is it compatible with putting the enable_if around there too?

推荐答案

,在短短时间内写了一篇博客文章,显示了一个不错的C ++ 11型SFINAE技术,容易允许重载功能。此技术和解释在提供。

Interestingly, a certain fellow here on SO wrote a blogpost just a short time ago, showing a nice C++11-style SFINAE technique that easily allows overloaded functions. The technique and explanation are provided here.

简而言之,您的代码失败,因为两个模板,当第一次解析和非依赖声明被解决时,完全相同,类型。与默认函数参数一样,默认模板参数只有在实际调用函数时才被替换。这是两个模板在编译器声明时的样子:

In short, your code fails because both templates, when parsed the first time and when non-dependant declarations are resolved, are exactly the same, type-wise. As with default function arguments, default template arguments are only substituted when the function is actually called. This is what both templates look like to the compiler at the point of declaration:

template<class T, unsigned Lt, class U, unsigned Lu, class Enable>
auto operator==(MyType<T,Lt> const& l, MyType<U,Lu> const& r);

以下代码应该实现您想要的:

The following code should achieve what you want:

namespace detail{
enum class enabler{};
}

template<bool B, class T = detail::enabler>
using EnableIf = typename std::enable_if<B, T>::type;

template < typename T, unsigned Lt, typename U, unsigned Lu, EnableIf<(Lt < Lu)>...>
auto  operator ==( MyType<T,Lt> const &l, MyType<U,Lu> const &r )
 -> decltype( std::declval<T>() == std::declval<U>() )
{ /*...*/ }

template < typename T, unsigned Lt, typename U, unsigned Lu, EnableIf<(Lt > Lu)>...>
auto  operator ==( MyType<T,Lt> const &l, MyType<U,Lu> const &r )
 -> decltype( std::declval<T>() == std::declval<U>() )
{ /*...*/ }

然而,一个问题仍然存在,如果 Lt == Lu ,会发生什么?在这种情况下,这两种过载都是不可行的。

One question remains, however... what should happen if Lt == Lu? In that case, neither overload is viable.

这篇关于如何对互斥的非成员函数模板使用enable_if?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 18:51