适当的模板使用

时间:2012-02-06 18:54:36

标签: c++ templates coding-style iterator generic-programming

假设我有一个名为Object的类。 Object类有一个成员函数,它想要从容器中读取字符串。假设函数看起来像这样:

template <class InputIterator>
void Object::add(InputIterator first, InputIterator last) { ... }

虽然这允许调用者从任意容器传递字符串,但它并不表示迭代器必须是一对字符串迭代器。

在这种情况下使用模板是否仍然合适,还是应该强制调用者使用预定的字符串容器?

2 个答案:

答案 0 :(得分:5)

不幸的是,C ++目前不允许您以简洁的方式编写此类信息。

C ++ 11应该用concepts来解决这个问题,但是由于一些概念(heh)的缺陷(which have in the meantime been solved,据我所知),它们在发布之前就被淘汰了。 p>

但是你仍然可以使用静态断言和类型特征提供这样的概念。例如,C ++ 11允许编写以下代码:

template <class InputIterator>
void Object::add(InputIterator first, InputIterator last) {
    static_assert(
        std::is_same<
            typename std::remove_cv<
                typename std::iterator_traits<InputIterator>::value_type
            >::type,
            std::string>::value,
        "InputIterator must be of iterator type");
    …
}

但是,假设InputIterator是有效的迭代器类型。由于没有特征is_iterator并且没有任何有意义的方法来实现它(据我所知),除非检查all required operations of an input iterator是否被遵守,这使得它理论上要困难得多。

答案 1 :(得分:-1)

正如Konrad Rudolph所提到的,你可能会失去模板构造,只是让add方法的签名具有字符串迭代器。或者保留模板构造。 add的实现可以通过调用的内容强制参数为字符串迭代器。 喜欢,

add(InputIterator first, InputIterator last) {
if ( first.begin == last.end) { do something }
}

这不需要first和last是字符串迭代器,但如果first.begin和/或last.end不合法,编译器会抱怨。

相关问题