gpt4 book ai didi

c++ - 当模板参数是 bidirectional_iterator 时如何启用模板类特化?

转载 作者:太空宇宙 更新时间:2023-11-04 12:37:49 24 4
gpt4 key购买 nike

我想创建一个模板类,它只接受双向迭代器作为其构造函数中的参数(用于初始化其数据成员)。

我正尝试为此使用enable_ifiterator_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<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 */, "!");
};

关于c++ - 当模板参数是 bidirectional_iterator 时如何启用模板类特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55594780/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com