CTM*_*ser 6 c++ templates sfinae c++11
我正在尝试编写非成员运算符函数模板,如:
#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>() )
{ /*...*/ }
Run Code Online (Sandbox Code Playgroud)
但是当我尝试处理时间l
和r
长度不同时:
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>() )
{ /*...*/ }
Run Code Online (Sandbox Code Playgroud)
我得到歧义错误.我尝试过类似的东西:
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>() )
{ /*...*/ }
Run Code Online (Sandbox Code Playgroud)
我已经读过(这里是SO)来解决成员函数模板这样的问题.(有时,受访者将成员函数更改为成员函数模板以启用此功能.)但错误不会因我而改变.我是否必须切换到enable_if
返回类型?
哦,当无法比较两种元素类型时,返回类型表达式应该排除此运算符.它真的有效吗?它与enable_if
周围的那个兼容吗?
Xeo*_*Xeo 11
有趣的是,SO上的某个人在不久前写了一篇博文,展示了一个很好的C++ 11风格的SFINAE技术,可以轻松实现重载功能.这里提供了技术和解释.
简而言之,您的代码会失败,因为在第一次解析时和解析非依赖声明时,两个模板都是完全相同的类型.与默认函数参数一样,默认模板参数仅在实际调用函数时被替换.这是两个模板在声明时对编译器的看法:
template<class T, unsigned Lt, class U, unsigned Lu, class Enable>
auto operator==(MyType<T,Lt> const& l, MyType<U,Lu> const& r);
Run Code Online (Sandbox Code Playgroud)
以下代码应该实现您想要的:
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>() )
{ /*...*/ }
Run Code Online (Sandbox Code Playgroud)
然而,一个问题仍然是......如果会发生Lt == Lu
什么?在这种情况下,过载都不可行.