templates - SFINAE 上缺少一些内容(虚拟模板参数形式)

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

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

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

Boost.Range 不提供“这是一个范围”检查,所以我使用 range_value<X>::value 因为如果指定类型不是范围,则依赖类型不存在。这正是 SFINAE 的意义所在!当我给它一个 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 };
}

当我给它一个有效的参数时,它就会编译。
当我给它 double ,而不是匹配其他构造函数,它提示

'type': is not a member of 'boost::range_iterator'

这绝对不是 SFINAE。


我在这里缺少什么?

最佳答案

问题在于如何 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成员(member)typedef ,但是boost::range_value<R>不是有效类型,因为它不能继承自 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成员(member),

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

关于templates - SFINAE 上缺少一些内容(虚拟模板参数形式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49826802/

相关文章:

javascript - sails js模板jst.js错误找不到变量_

c++ - 为什么指针类型转换不适用于模板非类型参数

c - 如何在 MSVC 中将每个源文件视为一个单独的程序

c++ - 特化 std::vector 的模板

c++ - C++ 函数中 "return"的确切时刻

asp.net-mvc-3 - 可重用的编辑器模板,带有用于业务对象的 DropDownList

C++矩阵类模板

c++ - 在 Windows XP 中多次启动程序 + DLL 时出现问题?

c++ - 如何在应用程序之间共享图像数据?

c++ - 什么时候 std::string_view::operator== 真的是 constexpr?