C ++:静态函数的模板?

时间:2010-05-28 01:10:18

标签: c++ templates syntax stl

我有一个静态的Utils类。我希望某些方法可以模板化,但不是整个类。我该怎么做?

这失败了:

#pragma once

#include <string>
using std::string;

class Utils
{
private:
    template<class InputIterator, class Predicate>
    static set<char> findAll_if_rec(InputIterator begin, InputIterator end, Predicate pred, set<char> result);

public:
    static void PrintLine(const string& line, int tabLevel = 0);
    static string getTabs(int tabLevel);

    template<class InputIterator, class Predicate>
    static set<char> Utils::findAll_if(InputIterator begin, InputIterator end, Predicate pred);
};

错误:

utils.h(10): error C2143: syntax error : missing ';' before '<'
utils.h(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
utils.h(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
utils.h(10): error C2238: unexpected token(s) preceding ';'
utils.h(10): error C2988: unrecognizable template declaration/definition
utils.h(10): error C2059: syntax error : '<'

我做错了什么?这个的正确语法是什么?

顺便说一下,我也想回归一下这个回报价值。所以而不是:

template<class InputIterator, class Predicate>
static set<char> findAll_if_rec(InputIterator begin, InputIterator end, Predicate pred, set<char> result);

我有:

template<class return_t, class InputIterator, class Predicate>
static return_t findAll_if_rec(InputIterator begin, InputIterator end, Predicate pred, set<char> result);

我如何指定:

1)return_t必须是某种

的集合

2)InputIterator必须是迭代器

3)InputIterator的类型必须与return_t的类型一起使用。

感谢。

更新:为了回应那些说我应该使用Java / C#样式的Utils类的名称空间的人,这是你想要的更多:

Utils.h

#pragma once

#include <string>
#include <set>
using std::set;
using std::string;

namespace Utils
{
    static void PrintLine(const string& line, int tabLevel = 0);
    static string getTabs(int tabLevel);

    template<class result_t, class Predicate>
    set<result_t> Utils::findAll_if(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred);
};

Utils.cpp

#include "Utils.h"
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;

void Utils::PrintLine(const string& line, int tabLevel)
{
    string tabs = getTabs(tabLevel);

    cout << tabs << line << endl;
}

string Utils::getTabs(int tabLevel)
{
    string tabs;
    while (tabLevel != 0)
    {
        tabs += "\t";
        tabLevel--;
    }
    return tabs;
}

template<class result_t, class Predicate>
set<result_t> Utils::findAll_if(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred)
{
    set<char> result;
    return findAll_if_rec(begin, end, pred, result);
}

template<class result_t, class Predicate>
set<result_t> findAll_if_rec(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred, set<result_t> result)
{
    InputIterator nextResultElem = find_if(begin, end, pred);
    if (nextResultElem == end)
    {
        return result;
    }
    result.add(*nextResultElem);

    return findAll_if_rec(++nextResultElem, end, pred, result);
}

这有很多编译器错误。我认为我没有正确使用result_t模板参数。

更新2 根据Georg的评论:

Utils.h

#pragma once

#include <string>
#include <set>
using std::set;
using std::string;

namespace Utils
{
    void PrintLine(const string& line, int tabLevel = 0);
    string getTabs(int tabLevel);

    template<class result_t, class Predicate>
    set<result_t> Utils::findAll_if(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred);
};

namespace detail
{
    template<class result_t, class Predicate>
    set<result_t> findAll_if_rec(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred, set<result_t> result);
};

Utils.cpp

#include "Utils.h"
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;

void Utils::PrintLine(const string& line, int tabLevel)
{
    string tabs = getTabs(tabLevel);

    cout << tabs << line << endl;
}

string Utils::getTabs(int tabLevel)
{
    string tabs;
    while (tabLevel != 0)
    {
        tabs += "\t";
        tabLevel--;
    }
    return tabs;
}

set<result_t> Utils::findAll_if(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred)
{
    set<char> result;
    return findAll_if_rec(begin, end, pred, result);
}

set<result_t> detail::findAll_if_rec(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred, set<result_t> result)
{
    InputIterator nextResultElem = find_if(begin, end, pred);
    if (nextResultElem == end)
    {
        return result;
    }
    result.add(*nextResultElem);

    return findAll_if_rec(++nextResultElem, end, pred, result);
}

仍然没有编译。帮助

更新3:越来越近了......

Utils.h:

#pragma once

#include <string>
#include <set>
using std::set;
using std::string;

namespace Utils
{
    void PrintLine(const string& line, int tabLevel = 0);
    string getTabs(int tabLevel);

    template<class result_t, class Predicate>
    set<result_t> Utils::findAll_if(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred)
    {
        set<result_t> result;
        return findAll_if_rec(begin, end, pred, result);
    }
}

namespace detail
{
    template<class result_t, class Predicate>
    set<result_t> findAll_if_rec(set<result_t>::iterator begin, set<result_t>::iterator end, Predicate pred, set<result_t> result)
    {
        set<result_t>::iterator nextResultElem = find_if(begin, end, pred);
        if (nextResultElem == end)
        {
            return result;
        }
        result.add(*nextResultElem);

        return findAll_if_rec(++nextResultElem, end, pred, result);
    }
}

Utils.cpp:

#include "Utils.h"
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;

void Utils::PrintLine(const string& line, int tabLevel)
{
    string tabs = getTabs(tabLevel);

    cout << tabs << line << endl;
}

string Utils::getTabs(int tabLevel)
{
    string tabs;
    while (tabLevel != 0)
    {
        tabs += "\t";
        tabLevel--;
    }
    return tabs;
}

仍然无法编译。

2 个答案:

答案 0 :(得分:4)

它抱怨返回类型 - set<char>:您忘记包含<set>并使用using std::set(或者最好只输入您使用它的std::set

至于强制模板参数满足某些要求,最简单的方法就是编写代码,使其假定类型满足这些要求。如果类型不符合这些要求,编译将失败。

答案 1 :(得分:0)

如果你总是希望按照设置返回,那么你可以让你的函数返回一个模板参数是你函数的模板参数的集合:

template<class set_t, class InputIterator, class Predicate>
static std::set<set_t> findAll_if_rec(InputIterator begin, InputIterator end, Predicate pred, std::set<set_t> result);