繁体   English   中英

enable_if iterator作为默认模板参数?

[英]enable_if iterator as a default template parameter?

我有一个像这样的构造函数:

class MyClass
{
    template<class TI> MyClass(TI first, TI last);
};

template<class TI> MyClass::MyClass(TI first, TI last)
{
    ;
}

我想只在TI是一个迭代器时启用这个构造函数(这意味着我认为TI有一个iterator_category)。 如何在C ++ 2011中使用enable_if作为默认模板参数(在声明和定义中)?

非常感谢你。

这取决于你想要什么。 如果没有其他重载,它可以没有任何东西 如果传递的类型不提供必要的操作,编译器将产生错误。

如果你真的想把它限制为迭代器,最好用static_assert来做,因为它会产生一个错误,带有一个很好的自定义错误信息,而不是“模糊的函数调用,这里有我可以找到的无数重载: 无穷无尽重载列表 “或”找不到功能,自己找“。

如果有另一个模板化的重载冲突,那么你确实需要一些enable_if的东西。 我写了一篇关于使用enable_if和C ++ 11特性的博客文章,以及为什么默认模板参数不是很好。 我决定用这样的东西代替:

enum class enabler {};

template <typename Condition>
using EnableIf = typename std::enable_if<Condition::value, enabler>::type;


class MyClass
{
    template<class TI, EnableIf<is_iterator<TI>>...> MyClass(TI first, TI last);
};

template<class TI, EnableIf<is_iterator<TI>>...> MyClass::MyClass(TI first, TI last)
{ /* blah */ }

您现在需要的只是测试的特征。 我认为测试iterator_category的存在就足够了,但它应该用std::iterator_traits来完成,因为指针是迭代器而且没有嵌套的typedef。

这可以通过使用SFINAE的常规技术来完成。 使用C ++ 11,我执行以下操作:

template <typename T>
struct sfinae_true : std::true_type {};

struct is_iterator_tester {
    template <typename T>
    static sfinae_true<typename std::iterator_traits<T>::iterator_category> test(int);

    template <typename>
    static std::false_type test(...);
};

template <typename T>
struct is_iterator : decltype(is_iterator_tester::test<T>(0)) {};

总而言之,这可以通过使用默认函数参数的传统技术来完成:

class MyClass
{
    template<class TI>
    MyClass(TI first, TI last,
            typename std::iterator_traits<T>::iterator_category* = nullptr)
};

template<class TI>
MyClass::MyClass(TI first, TI last,
                 typename std::iterator_traits<T>::iterator_category*)
{ /* blah */ }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM