缺少SFINAE上的内容(虚拟模板参数表)

时间:2018-04-14 00:42:16

标签: templates visual-c++ c++17 sfinae

我正在使用Visual Studio 17.7预览版3,包括Boost 1.67.0b1。

我是使用end的老手,但今天我正在尝试使用新的做事方式 - 一个虚拟的额外模板参数。

Boost.Range没有提供“这是一个范围”检查,所以我使用range_value<X>::value因为如果指定的类型不是范围,则依赖类型不存在。这正是SFINAE的全部意义所在!当我给它一个enable_if时,模板无法解析声明,所以它应该从重载集中删除而没有错误。

double

当我给它一个有效参数时,它会编译。
当我给它一个#include <boost/range/value_type.hpp> class Fizzer_t { public: using itemdef_t = std::pair<int, std::string_view>; private: std::vector<itemdef_t> playdef; public: template<typename R, typename = typename boost::range_value<R>::type> // only call if R is a "range" Fizzer_t (const R & range_of_itemdefs); Fizzer_t (double); // dummy }; void play2 { Fizzer_t player3{ 3.14 }; } ,而不是匹配其他构造函数时,它会抱怨

  

&#39;键入&#39;:不是&#39; boost :: range_iterator&#39;

的成员

最明显 SFINAE。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

问题在于如何定义boost::range_value类。

namespace boost
{
    template< class T >
    struct range_value : iterator_value< typename range_iterator<T>::type >
    { };
}

因此,当编译器到达代码中的行

typename = typename boost::range_value<R>::type

并非boost::range_value<R>没有type成员typedef,但boost::range_value<R>无法成为有效类型,因为它可以&#39 ; t继承自iterator_value< typename range_iterator<T>::type >,因为那个也失败了。

因此原始错误:

error: no type named 'type' in 'struct boost::range_iterator<double, void>'

快速修复就是写

typename = typename boost::range_value<R>

E.I。最后删除::type。或者,您可以直接检查boost::range_iterator<R>是否有type成员,

typename = typename boost::range_iterator<R>::type