Hello I am getting the following error
templateatt.cpp:4:32: error: expected template-name before ‘<‘ token
templateatt.cpp:4:32: error: expected â{â before ‘<‘ token
templateatt.cpp:4:32: error: expected unqualified-id before ‘<‘ token
When I compile the following cpp file:
#include<iostream>
template <class R, class T>
class mem_fun_t: unary_function<T*, R> {
R (T::*pmf)();
public:
explicit mem_fun_t(R (T::*p)()):pmf(p){}
R operator() (T *p) const { return (p->*pmf()); }
};
int main() {
return 0;
}
Any help will be great. I Am stuck at this.
Don't forget to #include <functional> to get unary_function and then qualify it with std::unary_function.
Related
I have a problem with real-world code and have replicated the problem with the following sample code.
#include <iostream>
#include <tuple>
using namespace std;
struct Identity
{
template <typename... T>
static std::tuple<T...> Apply(T... val)
{
return std::tuple(val...);
}
};
template <typename F, typename... T>
std::tuple<T...> Apply(T... t)
{
return F::Apply<T...>(t...);
}
int main()
{
const auto t = Apply<Identity>(1., 2., 3.);
cout << std::get<0>(t);
cout << std::get<1>(t);
cout << std::get<2>(t);
return 0;
}
Compilation error:
main.cpp:26:22: error: expected primary-expression before ‘...’ token
return F::Apply<T...>(t...);
^~~
main.cpp:26:22: error: expected ‘;’ before ‘...’ token
main.cpp:26:22: error: expected primary-expression before ‘...’ token
If I remove <T...> from the problematic statement, i.e. return F::Apply(t...);, and let the compiler deduce the type, it works. However, in my real world code I need to specify the types. What is the correct syntactical sugar to specific the types and satisfy the compiler?
You are missing one keyword. You need:
return F::template Apply<T...>(t...);
And it'll be fine. This error message is not the clearest one. :)
You can find an explanation here if you are interested in the details:
Where and why do I have to put the "template" and "typename" keywords?
Consider (link):
#include <cstdlib>
#include <cassert>
#pragma pack (1)
template <size_t Width>
class Base
{
public:
char mData [Width];
template <typename Field> Field ExtractAs () const
{
return *reinterpret_cast <Field> (mData);
}
};
template <typename FieldVal>
class IntegralField
:
public Base <sizeof (FieldVal)>
{
public:
FieldVal GetVal () const
{
return ExtractAs <FieldVal> ();
}
};
int main()
{
char raw[4] = {0x11, 0x22, 0x33, 0x44};
typedef IntegralField <uint32_t> UInt32Field;
const UInt32Field& field =
*reinterpret_cast <const UInt32Field*> (raw);
const uint32_t extracted = field.GetVal();
assert (extracted == 0x44332211);
}
The call:
return ExtractAs <FieldVal> ();
Fails to compile under g++ 4.7.2 with:
main.cpp: In member function ‘FieldVal IntegralField<FieldVal>::GetVal() const’:
main.cpp:25:16: error: ‘ExtractAs’ was not declared in this scope
main.cpp:25:35: error: expected primary-expression before ‘>’ token
main.cpp:25:38: error: expected primary-expression before ‘)’ token
main.cpp: In function ‘int main()’:
main.cpp:32:28: error: ‘uint32_t’ was not declared in this scope
main.cpp:32:36: error: template argument 1 is invalid
main.cpp:32:49: error: invalid type in declaration before ‘;’ token
main.cpp:35:11: error: ‘uint32_t’ does not name a type
main.cpp:36:5: error: ‘extracted’ was not declared in this scope
ninja: build stopped: subcommand failed.
I have tried a number of tricks including using Base::ExtractAs, typedefs, etc, to no avail.
Is what I'm trying to do possible in C++03? How can I call a function template in a base class template from a derived class template member function? Note that I cannot use C++11.
Edit: When I redefine GetVal to be more explicit about types:
FieldVal GetVal () const
{
static const size_t fieldSize = sizeof (FieldVal);
typedef Base <fieldSize> MyBase;
typedef FieldVal MyField;
return MyBase::ExtractAs <MyField> ();
}
I still get:
error: expected primary-expression before ‘>’ token
On: return MyBase::ExtractAs <MyField> ();
Edit: Here is the final, working code:
#include <cstdlib>
#include <cassert>
#include <stdint.h>
#pragma pack (1)
template <size_t Width>
class Base
{
public:
char mData [Width];
template <typename Field> Field ExtractAs () const
{
return *reinterpret_cast <const Field*> (mData);
}
};
template <typename FieldVal>
class IntegralField
:
public Base <sizeof (FieldVal)>
{
public:
FieldVal GetVal () const
{
return this->template ExtractAs<FieldVal>();
}
};
int main()
{
char raw[4] = {0x11, 0x22, 0x33, 0x44};
typedef IntegralField <uint32_t> UInt32Field;
const UInt32Field& field =
*reinterpret_cast <const UInt32Field*> (raw);
const uint32_t extracted = field.GetVal();
assert (extracted == 0x44332211);
}
You can either say:
return this->template ExtractAs<FieldVal>();
Or
return Base<sizeof(FieldVal)>::template ExtractAs<FieldVal>();
Since you are in a class template and the base is a template specialization, too, the names of base members are not automatically injected into the derived template. (Consider what happens if you specialize Base!)
By qualifying the name or using this->, you make the entire name dependent, and so it doesn't cause in error in the first phase. Also, since the name ExtractAs is dependent (being the nested name of a template), you have to disambiguate it as template.
i'm studing templates in c++ and according to this tutorial: http://www.cprogramming.com/tutorial/templates.html
i made the class CalcTempl.h
#ifndef CALC_TEMPL_H
#define CALC_TEMPL_H
template <class A_Type> class CalcTempl
{
public:
A_Type multiply(A_Type x, A_Type y);
A_Type add(A_Type x, A_Type y);
};
template <class A_Type> A_Type calc<A_Type>::multiply(A_Type x,A_Type y)
{
return x*y;
}
template <class A_Type> A_Type calc<A_Type>::add(A_Type x, A_Type y)
{
return x+y;
}
#endif
and main.cpp
#include <iostream>
#include "CalcTempl.h"
using namespace std;
int main(){
CalcTempl<double> c2;
double d1 = 5;
double d2 = 4;
double c2r1 = c2.add(d1, d2);
cout << " C2 Result: " << c2r1 << "\n";
return 0;
}
on compile (g++ main.cpp -o ttest) i got this error:
CalcTempl.h:11: error: expected init-declarator before '<' token
CalcTempl.h:11: error: expected `;' before '<' token
CalcTempl.h:15: error: expected init-declarator before '<' token
CalcTempl.h:15: error: expected `;' before '<' token
I can't found what is wrong
Your class is called CalcTempl, but at the point where you implement its members, you try to refer to it as calc. That can't work.
I am trying to pass a template typedef as argument to a function template. However I get following errors:
TestTemplates.cpp:11: error: expected unqualified-id before ‘&’ token
TestTemplates.cpp:11: error: expected unqualified-id before ‘&’ token
TestTemplates.cpp:11: error: expected initializer before ‘&’ token
TestTemplates.cpp:25: error: ‘func’ was not declared in this scope
#include <iostream>
#include <vector>
template<class T>
struct MyVector
{
typedef std::vector<T> Type;
};
template<class T>
void func( const MyVector<T>::Type& myVec )
{
for( MyVector<T>::Type::const_iterator p = myVec.begin(); p != myVec.end(); p++)
{
std::cout<<*p<<"\t";
}
}
int main()
{
MyVector<int>::Type myVec;
myVec.push_back( 10 );
myVec.push_back( 20 );
func( myVec );
}
Can anyone point out how to fix this error. I have looked at some posts, but cannot find the solution. Thanks
You need to tell the compiler that it's a typename
void func( const typename MyVector<T>::Type& myVec )
Then you need to explicitly help the compiler deduce the type for the function:
func<int>( myVec );
BTW, the issue is called "two stage lookup"
I don't understand what is wrong with the declaration of the derived file. Please help me find the issue with it.
This is the content of my header file:
/*
* STLSandbox.h
*
* Created on: Aug 4, 2012
* Author: aksinghdce
*/
#ifndef STLSANDBOX_H_
#define STLSANDBOX_H_
namespace amit {
class STLSandbox {
public:
STLSandbox();
virtual ~STLSandbox();
};
template<typename T>
class MyCotainer{
public:
virtual void inserthere(T&) = 0;
virtual void deletehere(T&) = 0;
virtual const void printhere(T&) = 0; //promise not to modify anything
};
template<typename T>
class VectorOf: public MyContainer<T>
{
public:
virtual void inserthere(T&);
virtual void deletehere(T&);
virtual const void printhere(T&);
private:
std::vector<T&> v_data; // vector of references of type T
};
template<typename T>
void VectorOf<T>::inserthere(T& item){
v_data.push_back(item);
}
template<typename T>
void VectorOf<T>::deletehere(T& item){
v_data.pop_back(item);
}
template<typename T>
const void VectorOf<T>::printhere(T& item){
std::vector<T>::iterator i = null;
for(i=v_data.begin();i<v_data.end();i++)
{
std::cout<<*i<<std::endl;
}
}
}
#endif /* STLSANDBOX_H_ */
I am using gcc 4.2.1
The following are the error I am getting:
[...]/STLSandbox.h:26: error: expected template-name before ‘<’ token
[...]/STLSandbox.h:26: error: expected `{' before ‘<’ token
[...]/STLSandbox.h:26: error: expected unqualified-id before ‘<’ token
[...]/STLSandbox.h:37: error: ‘template<class T> class amit::VectorOf’ used without template parameters
[...]/STLSandbox.h: In function ‘void amit::inserthere(T&)’:
[...]/STLSandbox.h:38: error: ‘v_data’ was not declared in this scope
[...]/STLSandbox.h: At global scope:
[...]/STLSandbox.h:42: error: ‘template<class T> class amit::VectorOf’ used without template parameters
Looks like its just a typo. You have defined the class MyCotainer (note the missing n) but are using the correct MyContainer later.