我正在使用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。
我在这里缺少什么?
答案 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