【发布时间】:2019-04-09 14:06:07
【问题描述】:
我想创建一个模板类,它只接受双向迭代器作为其构造函数中的参数(用于初始化其数据成员)。
我正在尝试为此使用 enable_if 和 iterator_category,但我不明白出了什么问题。我在带有 -std=c++17 的 Linux 上同时使用 gcc 8.3.1 和 clang 7。我还在Compiler Explorer 上尝试过其他编译器。
(注意:我也尝试过使用 is_same_v 代替 is_base_of_v,但结果相同,或者缺少...)
#include <iterator>
#include <type_traits>
#include <vector>
template<typename It>
using it_cat = typename std::iterator_traits<It>::iterator_category;
template<typename BidIt,
typename std::enable_if_t<std::is_base_of_v<it_cat<BidIt>, std::bidirectional_iterator_tag>> = 0
>
class A {
BidIt start;
public:
// A() : start {} {}
A(BidIt s_) : start {s_} {}
};
// A<std::vector<int>::iterator> a1;
int main()
{
std::vector<int> v {0, 1, 2, 3};
A a2 {v.begin()};
}
注释的两行试图通过显式传递参数来手动实例化 A 类型的空对象(没有成功)。编译器输出清楚地显示类型推导失败:
error: no type named 'type' in 'struct std::enable_if<false, void>'
typename std::enable_if_t<std::is_base_of_v<it_cat<BidIt>, std::bidirectional_iterator_tag>> = 0
据我了解,enable_if 被评估为 false。
【问题讨论】:
-
投票结束是一个错字。
std::is_base_of_v的参数是向后的,> = 0应该是>* = nullptr