如何在模板参数为bidirectional_iterator时启用模板类专用化
How to enable a template class specialization when the template parameter is a bidirectional_iterator?
我想创建一个模板类,该模板类仅接受双向迭代器作为其构造函数中的参数(用于初始化其数据成员(。
我正在尝试为此使用enable_if和iterator_category,但我不明白出了什么问题。我在 Linux 上使用 gcc 8.3.1 和 clang 7,带有 -std=c++17。我还在编译器资源管理器上尝试了其他编译器。
(注意:我也尝试使用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被评估为假。
首先,你倒退使用特质。 std::is_base_of<Base, Derived>
检查第一个是否是第二个的基础。所以你的支票应该是is_base_of_v<bidirectional_iterator_tag, it_cat<BidIt>>
的。
其次,执行这种条件启用(假设您想要其他专用化(的 C++17 习惯用法是具有默认的第二个模板参数:
template <typename T, typename Enable = void>
struct X; // the primary
template <typename T>
struct X<T, std::enable_if_t</* condition */>> // the conditional specialization
{ ... };
如果您不需要其他专业,我们可以通过更简单的方式做到这一点:
template <typename T>
struct X {
static_assert(/* the condition */, "!");
};
相关文章:
- 编译时未启用intel oneApi CUDA支持
- OpenGL在启用深度测试时不会丢弃我的碎片
- Visual C++GC接口如何启用它以及要包含哪个库
- 如何在自定义类中启用'auto loops'?
- 根据某个函数是否存在启用模板
- 视觉工作室 2017;启用 /permissive 时,类型 "const wchar_t *" 的参数与类型 "PWSTR" 的参数不兼容
- 启用从"vector<const T>&"到"const vector&"的隐式转换<T>
- 在调试模式下引发C++ "deque iterator not dereferencable"异常
- C++ win32 如何使密码字段可选并启用复制和粘贴?
- std::iterator::reference 必须是引用吗?
- 在 Eclipse 上启用 C++17 以使用 'std::byte'
- 为什么unordered_set<string::iterator>不起作用?
- 当 noexcept 函数尝试在 gcc 或 clang 中调用非 noexcept 函数时启用警告
- 如何为一段代码启用 -permissive
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 在 GCC 中启用"differing levels of indirection"警告/错误
- 使用 Doxygen 记录枚举类值,而不启用EXTRACT_ALL
- '_HAS_CXX17'宏是否可用于自定义项目标头以启用C++17 语言集功能?
- 如何启用转换模板参数 T 以常量 T?
- 在使用 gSoap 链接多个 SOAP 服务时启用保持活动状态