模板签名问题

发布于 2024-10-16 11:28:15 字数 1181 浏览 2 评论 0原文

我是使用模板的新手,需要使用模板来做某事,但不知道如何调用模板化函数。这可能很简单,但我看不到。

template<class It, class T>


// iterator and value_type of *It
void Calc(It begin, It end, std::pair<int, int> &out)
{
        std::vector<It>::iterator iter;
    std::map<int, int> StartMap;
    std::map<int, int>::reverse_iterator rit;

    int sum, start, stop, count;
    start = stop = 1;
    count = sum = 0;

    for(iter = begin; iter != end; iter++ )
    {
        sum += iter;
        count++;
        stop++;
        if(sum <= 0)
        {
            // store original start
            StartMap.insert(start, count);
            // set new start position
            start = stop;
        }   
    }

    // set iterator to highest value
    rit = StartMap.rbegin();

    start = rit->first;
    stop = start + rit->second;

    out.insert(start, stop);
}

但不知道如何用 2 个 std::vector 迭代器调用它。 我试过这个

void doSomething(std::vector<int>& stopsVec)
{
    std::pair<int, int> out;
    Calc<std::vector<int>::iterator, std::pair<int, int>>(stopsVec.begin(), stopsVec.end(), &out);
}

I am new to using templates and am required to use a template to do something, but don't know how to call the templated function. It's probably soething simple, but I can't see it.

template<class It, class T>


// iterator and value_type of *It
void Calc(It begin, It end, std::pair<int, int> &out)
{
        std::vector<It>::iterator iter;
    std::map<int, int> StartMap;
    std::map<int, int>::reverse_iterator rit;

    int sum, start, stop, count;
    start = stop = 1;
    count = sum = 0;

    for(iter = begin; iter != end; iter++ )
    {
        sum += iter;
        count++;
        stop++;
        if(sum <= 0)
        {
            // store original start
            StartMap.insert(start, count);
            // set new start position
            start = stop;
        }   
    }

    // set iterator to highest value
    rit = StartMap.rbegin();

    start = rit->first;
    stop = start + rit->second;

    out.insert(start, stop);
}

but not sure how I call it with 2 std::vector iterators.
I've tried this

void doSomething(std::vector<int>& stopsVec)
{
    std::pair<int, int> out;
    Calc<std::vector<int>::iterator, std::pair<int, int>>(stopsVec.begin(), stopsVec.end(), &out);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

荒人说梦 2024-10-23 11:28:15
void doSomething(std::vector<int>& stopsVec)
{
    std::pair<int, int> out;
    Calc<std::vector<int>::iterator, std::pair<int, int> >
        (stopsVec.begin(), stopsVec.end(), out);   // not &out
}

Calc 获取对 std::pair 的引用,因此您只需将其out 给出即可。传递 &out 尝试将指针传递给一对 - 这是行不通的。

编辑

假设签名实际上是:

template<class It>
void Calc(It begin, It end, std::pair<int, int> &out)

您可以使用以下方式调用它:

Calc(stopsVec.begin(), stopsVec.end(), out);

编译器可以从参数中推导出正确的模板类型,而不需要您在 <> 之间指定它们

编辑

基思在下面提出了一个很好的观点。这是您在这里会遇到的另一个编译错误。还要注意的是:

sum += iter;

没有做你想做的事。你可能的意思是:

sum += *iter;

但是由于 sum 是一个 int,而 iter 是一个模板类型,所以这并不是真正的通用模板方法。它实际上只适用于数字类型的迭代器。

而且,还有一个问题:

Calc<std::vector<int>::iterator, std::pair<int, int> >  // use a space
    (stopsVec.begin(), stopsVec.end(), out);

您需要在

Calc<std::vector<int>::iterator, std::pair<int, int>>  // ">>" is shift operator
    (stopsVec.begin(), stopsVec.end(), out);

结束 > 符号之间留一个空格才能使用模板语法。否则,您正在执行位移(或流提取),编译器会感到困惑,因为从那时起一切都没有意义。

void doSomething(std::vector<int>& stopsVec)
{
    std::pair<int, int> out;
    Calc<std::vector<int>::iterator, std::pair<int, int> >
        (stopsVec.begin(), stopsVec.end(), out);   // not &out
}

Calc takes a reference to std::pair<int, int>, so you want to just give it out. Passing &out tries to pass a pointer to a pair - which won't work.

EDIT

assuming the signature is actually:

template<class It>
void Calc(It begin, It end, std::pair<int, int> &out)

You can call it with:

Calc(stopsVec.begin(), stopsVec.end(), out);

The compiler can deduce the correct template type from the parameters, without requiring you to specify them between <>

EDIT

Keith makes a good point below. That's another compilation error you would have here. Also note that:

sum += iter;

does not do what you want. you probably meant:

sum += *iter;

But since sum is an int, and iter is a template type, this is not really a general-purpose template method. It's really only going to work for iterators over numeric types.

And, one other issue:

Calc<std::vector<int>::iterator, std::pair<int, int> >  // use a space
    (stopsVec.begin(), stopsVec.end(), out);

instead of

Calc<std::vector<int>::iterator, std::pair<int, int>>  // ">>" is shift operator
    (stopsVec.begin(), stopsVec.end(), out);

You need a space between the closing > signs in order to have template syntax. Otherwise you're doing bitshift (or stream extraction), and the compiler will get confused because nothing will make sense from that point on.

〆凄凉。 2024-10-23 11:28:15

注意:

template<class It, class T>
void Calc(It begin, It end, std::pair<int, int> &out)
{
    std::vector<It>::iterator iter;
    for(iter = begin; iter != end; iter++ )

是错误的。它可能应该是:

template<class It, class T>
    void Calc(It begin, It end, std::pair<int, int> &out)
    {
        It iter;
        // etc.
        for(iter = begin; iter != end; iter++ )

但还要注意,在 C++ 中,通常首选遵循“声明即初始化”方法,因此这变为:

  template<class It, class T>
        void Calc(It begin, It end, std::pair<int, int> &out)
        {
             // etc.
            for(It iter = begin; iter != end; iter++ )

Note that:

template<class It, class T>
void Calc(It begin, It end, std::pair<int, int> &out)
{
    std::vector<It>::iterator iter;
    for(iter = begin; iter != end; iter++ )

is wrong. It should probably be:

template<class It, class T>
    void Calc(It begin, It end, std::pair<int, int> &out)
    {
        It iter;
        // etc.
        for(iter = begin; iter != end; iter++ )

But also note that in C++, it is generally preferred to follow the 'declaration is initialisation' approach, so this becomes:

  template<class It, class T>
        void Calc(It begin, It end, std::pair<int, int> &out)
        {
             // etc.
            for(It iter = begin; iter != end; iter++ )
鹤舞 2024-10-23 11:28:15

您不需要将正在迭代的类型作为模板参数显式传递。 STL 设计者非常明智,他们意识到这种情况经常出现,并且有一种(不是很漂亮但完全正确)方法来内省迭代器的类型以获得其底层类型,如下所示:

typedef typename std::iterator_traits<It>::value_type value_type;

一旦完成此操作,您就可以可以使用名称 value_type 来引用正在迭代的类型。这使您可以将模板函数重写为

template <typename It>
void Calc(It begin, It end, std::pair<int, int>& out) {
     typedef typename std::iterator_traits<It>::value_type value_type;
     /* ... Rest of the code, now using this type ... */
}

并完成交易,既然不需要任何辅助类型,您可以直接调用该函数 希望

std::vector<int> v = /* ... */
std::pair<int, int> result;
Calc(v.begin(), v.end(), result);

这更容易阅读和编写!

You don't need to explicitly pass the type being iterated over as a template argument. The STL designers were quite wise and realized that this often comes up, and there's a (not very pretty but entirely correct) way to introspect on the type of an iterator to get it's underlying type as follows:

typedef typename std::iterator_traits<It>::value_type value_type;

Once you've done this, you can use the name value_type to refer to the type being iterated over. This lets you rewrite the template function as

template <typename It>
void Calc(It begin, It end, std::pair<int, int>& out) {
     typedef typename std::iterator_traits<It>::value_type value_type;
     /* ... Rest of the code, now using this type ... */
}

And to seal the deal, now that there aren't any auxiliary types required, you can call the function directly as

std::vector<int> v = /* ... */
std::pair<int, int> result;
Calc(v.begin(), v.end(), result);

Hopefully this is easier to read and write!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文