检查容器模板类中的迭代器类型

时间:2018-01-22 14:27:09

标签: c++ templates template-meta-programming

我正在编写一个容器类,并希望提供一个构造函数,将迭代器作为参数,但前提是底层迭代类型与容器类型匹配。

所以我写道:

template<typename T>
class Buffer
{
public:
    template <typename InputIter>
    typename std::enable_if<std::is_same<typename std::iterator_traits<InputIter>::value_type, typename T>>::type
    Buffer(InputIter first, InputIter last)
    {
    }
};

但我有编译错误,说模板参数1和2无效

有什么问题?

编码器代码:https://onlinegdb.com/SyIqN_mBG

2 个答案:

答案 0 :(得分:8)

几乎就在那里。正如评论中所说,你需要记住的是构造函数没有返回类型。 SFINAE在返回类型上的常用技巧不适用于它们。

但是他们可以拥有额外的模板参数,无论如何总是默认的,但仅仅存在可以用于SFINAE。因此,让我们使用您提供的非常测试(在添加缺少的::value之后)向c'tor添加非类型模板参数:

template<typename T>
class Buffer
{
public:
    template <typename InputIter, 
      typename std::enable_if<std::is_same<typename std::iterator_traits<InputIter>::value_type, T>::value, int>::type = 0>
    Buffer(InputIter first, InputIter last)
    {
    }
};

因此,如果迭代器是正确的,我们还有一个int = 0,如果不是,则SFINAE! c'tor从重载集中删除。

答案 1 :(得分:5)

SFINAE有3个可用的地方:

  • 作为返回类型
  • 作为参数类型
  • 作为模板类型

对于构造函数,不能使用返回类型。

我建议使用默认模板参数:

template<typename T>
class Buffer
{
public:
    template <typename InputIter,
              typename std::enable_if<
                           std::is_same<typename std::iterator_traits<InputIter>::value_type,
                                        T>::value,
                                      bool>::type = false>
    Buffer(InputIter first, InputIter last)
    {
    }
};