繁体   English   中英

我在与模板参数有关的问题

[英]I'm having problems relating to template arguments

template <class RandomIterator, class T>
T median(RandomIterator b, RandomIterator e)
{
    std::sort(b, e);

    int count = 0;

    for(RandomIterator ri = b; ri != e; ++ri)
        ++count;

    int mid = count / 2;

    return (count % 2 == 0) ? *(b+mid) : (*(b+mid) + *(b+mid+1)) / 2;
}

我在T类(中位数函数的返回类型)上遇到麻烦。 如果我将其取出并将T转换为int,它似乎可以工作,但会减少使用模板的含义。 救命!

切换模板参数的顺序:

template <class T, class RandomIterator> 
T median(RandomIterator b, RandomIterator e)

这样,您只需在通话时传递T类型:

median<int>(it1, it2);

或者,更好的是,完全摆脱T:

template <class RandomIterator> 
auto median(RandomIterator b, RandomIterator e) -> auto(*b) 

为了回答您的实际问题,模板的问题是编译器需要能够仅从函数调用中找出类型T是什么。 它之所以不能这样做,是因为T从不直接使用,当然也不在函数签名(不包括返回类型)中使用。

轻微改善

一种方法是在调用时显式声明它,例如median<std::vector<double>::iterator, double>(mvvec.begin(), myvec.end()); 但这相当笨拙。 更好的选择是在模板声明中交换RandomIteratorT的顺序,以便您可以仅指定返回类型: median<double>(myvec.begin(), myvec.end());

更好的改善

但是,在C ++ 11和更高版本中,您可以做得更好。 class T放到模板中,并使用auto,并在需要时指定迭代器的value_type: auto median(RandomIterator b, RandomIterator e) -> decltype(*b)您可能会发现decltype不必要。 但是,您还需要确定是否要返回一个值或一个引用-每种方法都有优缺点,所以我无法为您决定。

最佳方法

但是,您的函数与众不同之处在于,它们都在一个范围(一对迭代器)上运行,但返回一个值。 大多数STL算法都返回一个迭代器,因为它们不确定取消引用是否安全。 例如,假设您从一个空向量传递了begin()和end()。 通过返回迭代器,调用者可以决定取消引用。 这也解决了返回值或引用的问题。 然后,该调用只是median(mvvec.begin(), myvec.end()); -如果需要,请加一个参考。

算法细化

be必须是随机访问迭代器,因为您正在调用std::sort 但是,计数计算效率很低。 考虑简单地使用auto count = e - b; auto mid = count / 2; 使用auto将为您提供正确的difference_type,它并不总是与int相同。 通常它是ptrdiff_t,但是即使如此,良好的迭代器代码也不应假定。 如果不能使用autotypename std::iterator_traits<RandomIterator>::difference_type是正确的类型。

无需将返回类型指定为模板参数。 您可以使用以下方法访问迭代器的基础类型:

std::iterator_traits<RandomIterator>::value_type

如果仍然要这样做,则必须显式指定所有模板参数的类型,因为编译器无法通过使用提供的其他类型来唯一地推断出它。

我将其完全删除,如下所示:

template <class RandomIterator>
std::iterator_traits<RandomIterator>::value_type median(RandomIterator b, RandomIterator e)

甚至更好地使用自动

    template <class RandomIterator>
   auto median(RandomIterator b, RandomIterator e)

暂无
暂无

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

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