gpt4 book ai didi

c++ - enable_if 迭代器作为默认模板参数?

转载 作者:太空狗 更新时间:2023-10-29 23:36:51 24 4
gpt4 key购买 nike

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

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 东西。我写了一篇关于 using enable_if with C++11 features 的博文,以及为什么默认模板参数对此不是很好。我用这样的东西解决了:

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 */ }

关于c++ - enable_if 迭代器作为默认模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11898657/

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