Use either just
original.to_string();
or, if you really need the type specifiers,
original.template to_string<char, char_traits<char>, allocator<char> >();
Use either just
original.to_string();
or, if you really need the type specifiers,
original.template to_string<char, char_traits<char>, allocator<char> >();
The following compiled for me (using gcc 3.4.4):
#include <bitset>
#include <string>
using namespace std;
template <int N, int M>
bitset<N> slice_bitset(const bitset<M> &original, size_t start)
{
string str = original.to_string();
string newstr = str.substr(start, N);
return bitset<N>(newstr);
}
int main()
{
return 0;
}
The selected answer from CAdaker above solves the problem, but does not explain why it solves the problem.
When a function template is being parsed, lookup does not take place in dependent types. As a result, constructs such as the following can be parsed:
template <typename T>
class B;
template <typename T>
void foo (B<T> & b) {
// Use 'b' here, even though 'B' not defined
}
template <typename T>
class B
{
// Define 'B' here.
};
However, this "feature" has a cost, and in this case it is that the definition of 'foo' requires hints on the contents of the template 'B'. If 'foo' uses a nested type of 'B', then the typename
keyword is required to tell the compiler that the name is a type:
template <typename T>
void foo (B<T> & b)
{
typename B<T>::X t1; // 'X' is a type - this declares t1
B<T>::Y * t1; // 'Y' is an object - this is multiplication
}
Without 'typename' in the above the compiler will assume that X
is an object (or function).
Similarly, if a member function is called and the call has explicit template arguments then the compiler needs to know to treat the <
as the start of a template argument list and not the less than operator:
template <typename T>
void foo (B<T> & b)
{
b.template bar<int> (0); // 'bar' is a template, '<' is start of arg list
b.Y < 10; // 'Y' is an object, '<' is less than operator
}
Without template
, the compiler assumes that <
is the less than operator, and so generates the syntax error when it sees int>
since that is not an expression.
These hints are required even when the definition of the template is visible. The reason is that an explicit specialization might later change the definition that is actually chosen:
template <typename T>
class B
{
template <typename S>
void a();
};
template <typename T>
void foo (B<T> & b)
{
b.a < 10; // 'B<int>::a' is a member object
}
template <>
class B<int>
{
int a;
};