I have a static Utils class. I want certain methods to be templated, but not the entire class. How do I do this?
This fails:
#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);
};
Error:
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 : '<'
What am I doing wrong? What is the correct syntax for this?
Incidentally, I'd like to templatize the return value, too. So instead of:
template<class InputIterator, class Predicate>
static set<char> findAll_if_rec(InputIterator begin, InputIterator end, Predicate pred, set<char> result);
I'd have:
template<class return_t, class InputIterator, class Predicate>
static return_t findAll_if_rec(InputIterator begin, InputIterator end, Predicate pred, set<char> result);
How would I specify that:
1) return_t
must be a set of some sort
2) InputIterator
must be an iterator
3) InputIterator
's type must work with return_t
's type.
Thanks.
UPDATE: In response to people who say I should use a namespace intsead of a Java/C# style Utils class, is this more what you were looking for:
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);
}
This has many compiler errors. I don't think I'm using the result_t
template argument correctly.
Update 2 Based on Georg's comments:
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);
}
Still not compiling. Help?
Update 3: Getting closer...
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;
}
Still doesn't compile.