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

gal*_*tte 4 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)
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

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

怎么了?

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

Sto*_*ica 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)
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

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


Jar*_*d42 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)
    {
    }
};
Run Code Online (Sandbox Code Playgroud)