使用概念对任何具有特定值类型的容器进行C++迭代。

问题描述 投票:3回答:1

我想摆脱所有的邪恶。enable_if在我的模板中,用C++20的概念来代替它们,但是几乎没有任何关于概念的信息,而且我读到的所有源码的语法都在改变。

这里有一个函数,它可以接受任何容器的两个迭代器,并将它们与 MyClass 值。

template <class IteratorType, typename = std::enable_if<std::is_same<
                                typename std::iterator_traits<IteratorType>::value_type,
                                MyClass
                            >::value, void>>
void myFunction( IteratorType begin, IteratorType end ) {}

我知道这个函数可以用概念来转换 但我就是找不到好的线索来开始。

c++ sfinae c++20 enable-if c++-concepts
1个回答
5
投票

可能不是最容易理解的参考资料,但概念的规范信息来源是现有的标准草案。其中概念定义在语法上规定为

1 概念是一个模板,它定义了对其模板参数的约束。

concept-definition:
  concept concept-name = constraint-expression ;
concept-name:
  identifier

它和一个bool变量模板常量差不多,但它是用概念关键字定义的。所以,把你的条件直接翻译成概念,本质上是这样的

template<typename T>
concept MyClassIter = std::is_same_v<
                        MyClass, 
                        typename std::iterator_traits<T>::value_type
                      >;

有了这个概念,我们就可以把它作为模板的类型参数的类型约束,从而把你的模板转化为这个

template <MyClassIter IteratorType>
void myFunction( IteratorType begin, IteratorType end ) {}

如果一个类型的约束条件不满足,这个重载就会被丢弃。在这种情况下,不满足也包括替换失败。所以这和你原来的条件是一样的。

实例


3
投票

最直接的翻译是

template <typename IteratorType>
requires std::same_as<typename std::iterator_traits<IteratorType>::value_type, MyClass>
void myFunction(IteratorType begin, IteratorType end) {}

见。

上帝之门例子


2
投票

为了适应C++20的Ranges生态体系。

template <std::input_iterator I, std::sentinel_for<I> S>
    requires std::same_as<std::iter_value_t<I>, MyClass>
constexpr void myFunction(I begin, S end)
{
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.