C++ templates and structs problem - c++

I have this...
template <typename Key, typename Value>
class A {
public:
//...
private:
struct MyStruct{
Key key;
Value value;
};
};
And it gives me the following errors:
Error 1 error C2146: syntax error : missing ';' before identifier 'value'
Error 2 error C4430: missing type specifier - int assumed.
Error 3 error C4430: missing type specifier - int assumed.
Some specs:
Using Visual Studio 2010
Windows 7 x64
Can my error be before or after these lines?

You forgot a semicolon after the class definition, at the very end of your code.
In some cases you need to write typename Key key; instead of a simple Key key; in templates, since the compiler may not know that Key is really a typename. So try this:
template <typename Key, typename Value>
class A {
public:
//...
private:
struct MyStruct {
/* typename not allowed here */ Key key;
/* typename not allowed here */ Value value;
};
};

You forgot the last semi-colon to end your class definition.

It looks like you missed a semi-colon to close out your class.
This compiles fine for me using g++ 4.6.1:
#include <iostream>
template <typename Key, typename Value>
class A {
public:
A() {}
private:
struct MyStruct {
Key key;
Value value;
};
};
int main(void) {
A<int, char> a;
}

First, maybe it's just a typo in the code you pasted, but you are missing the ; at the end of the class definition.
Beyond that, I don't see a problem. Make sure you are declaring an object as
A<type, type> a;
What are you using for your template types?

Related

template alias in specialized class

The following code gives the error (in line where i define test):
error C2143: syntax error: missing ';' before '<'
note: see reference to class template instantiation 'ptc::Produce' being compiled
error C4430: missing type specifier - int assumed.
Note: C++ does not support default-int
Does anybody know why this happens?
Compiler is VC2015 CTP1.
Edit: the error must happen in phase1 of the template parsing, because it occurs even I never instantiate the class Produce.
namespace OrderPolicy
{
struct Unordered {};
struct Ordered {};
};
template <typename TOrderPolicy>
struct OrderManager {};
template<>
struct OrderManager<OrderPolicy::Unordered>
{
template <typename TItem>
using item_t = TItem;
};
template<>
struct OrderManager<OrderPolicy::Ordered>
{
template <typename TItem>
using item_t = TItem*;
};
template<typename TOrderPolicy>
struct Produce : public OrderManager<TOrderPolicy>
{
item_t<int> test;
//using item_type = item_t<int>;
};
Edit2: it works when I change the last part of the code to
struct Produce : public OrderManager<OrderPolicy::Ordered>
{
item_t<int> test;
//using item_type = item_t<int>;
};
item_t<int> test;
That names a dependent template type from a base class. In this case, you need to tell the compiler both that item_t is a type in your base class, and that it's a template.
The direct way to do this is using typename and template:
typename OrderManager<TOrderPolicy>::template item_t<int> test;
As you can see, this will quickly become unreadable. I would make some local aliases to make the code neater:
using Base = OrderManager<TOrderPolicy>;
using item_type = typename Base::template item_t<int>;
item_type test;
You'll have to use:
typename OrderManager<TOrderPolicy>::template item_t<int>
in place of:
item_t<int> test;
wow, learning never stops. Until now I did not see the keyword template used in this context.

How to get this template class to compile?

Sorry, I couldn't frame a question that could capture my problem properly. My problem is this.
I have a templated class like this. I am not able to understand how exactly to define the Get function.
template<class Data>
class Class
{
struct S
{
};
void Do();
S Get();
};
template<class Data>
void Class<Data>::Do()
{
}
template<class Data>
Class<Data>::S Class<Data>::Get()
{
}
I get the following errors
1>error C2143: syntax error : missing ';' before 'Class<Data>::Get'
1>error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>fatal error C1903: unable to recover from previous error(s); stopping compilation
template<class Data>
Class<Data>::S Class<Data>::Get()
needs to be
template<class Data>
typename Class<Data>::S Class<Data>::Get()
because S is a dependent type. Any time you have a type that's nested in a template you need to use the keyword typename. For example, an iterator over a vector<int> has the type typename vector<int>::iterator.
A C++11 style, easier to read and write :
template<class Data>
auto Class<Data>::Get() -> S {
return {};
}

Coding iterator function for STL Class

I am working through some C++ code from "Financial Instrument Pricing Using C++" - a book on option pricing using C++. Following code is a small snippet stripped of many details which basically attempts to define a SimplePropertySet class that is intended to contain a name and list.
#include <iostream>
#include <list>
using namespace::std;
template <class N, class V> class SimplePropertySet
{
private:
N name; // The name of the set
list<V> sl;
public:
typedef typename list<V>::iterator iterator;
typedef typename list<V>::const_iterator const_iterator;
SimplePropertySet(); // Default constructor
virtual ~SimplePropertySet(); // Destructor
iterator Begin(); // Return iterator at begin of composite
const_iterator Begin() const;// Return const iterator at begin of composite
};
template <class N, class V>
SimplePropertySet<N,V>::SimplePropertySet()
{ //Default Constructor
}
template <class N, class V>
SimplePropertySet<N,V>::~SimplePropertySet()
{ // Destructor
}
// Iterator functions
template <class N, class V>
SimplePropertySet<N,V>::iterator SimplePropertySet<N,V>::Begin()//<--this line gives error
{ // Return iterator at begin of composite
return sl.begin();
}
int main(){
return(0);//Just a dummy line to see if the code would compile
}
On compiling this code on VS2008, I obtain the following errors:
warning C4346: 'SimplePropertySet::iterator' : dependent name is not a type
prefix with 'typename' to indicate a type
error C2143: syntax error : missing ';' before 'SimplePropertySet::Begin'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Is there something stupid or basic that I am getting wrong or forgetting here? Is it a syntax error? I am unable to put my finger on it. The book from which this code snippet is taken says their code was compiled on Visual Studio 6. Is this some version-related issue?
Thanks.
As indicated by the compiler, you must replace :
template <class N, class V>
SimplePropertySet<N,V>::iterator SimplePropertySet<N,V>::Begin()
with :
template <class N, class V>
typename SimplePropertySet<N,V>::iterator SimplePropertySet<N,V>::Begin()
See this link for an explanation on dependent names.

Simple C++ template definition problem

I'm new to C++. Here is the code:
template <class T> typename lw_slist {
// .... some code
private:
typedef struct _slist_cell {
_slist_cell *next;
T data;
} slist_cell;
lw_slist::slist_cell *root;
};
Give this compilation error:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Why?
It's an error because that isn't any kind of declaration at all.
The compiler needs to know if you want a class, struct, enum, union or something else. typename is not the right keyword to use there.
You are probably looking for this:
template<class T>
struct lw_slist {
};
A whole new question, a whole new answer:
I think that you will want it like this:
template <class T>
class lw_slist {
// .... some code
private:
struct slist_cell {
slist_cell *next;
T data;
};
slist_cell *root;
};
There is no reason to use a typedef: C++ makes classes and structs automatically part of the namespace.
There is no reason to use lw_slist::slist_cell because slist_cell is already in the current namespace.
The reason that you were getting the error dependent name is not a type is that inside a template declaration C++ cannot tell if lw_slist<T>::slist_cell is supposed to be a type or a variable. It assumes a variable named slist_cell and you have to use typename to say otherwise.

Mapping integers to types using C++ template fails in a specific case

I am attempting to compile the following template based code in VC++ 2005.
#include <iostream>
using namespace std;
/*
* T is a template which maps an integer to a specific type.
* The mapping happens through partial template specialization.
* In the following T<1> is mapped to char, T<2> is mapped to long
* and T<3> is mapped to float using partial template specializations
*/
template <int x>
struct T
{
public:
};
template<>
struct T<1>
{
public:
typedef char xType;
};
template<>
struct T<2>
{
public:
typedef long xType;
};
template<>
struct T<3>
{
public:
typedef float xType;
};
// We can easily access the specific xType for a specific T<N>
typedef T<3>::xType x3Type;
/*!
* In the following we are attempting to use T<N> inside another
* template class T2<R>
*/
template<int r>
struct T2
{
//We can map T<r> to some other type T3
typedef T<r> T3;
// The following line fails
typedef T3::xType xType;
};
int main()
{
T<1>::xType a1;
cout << typeid(a1).name() << endl;
T<2>::xType a2;
cout << typeid(a2).name() << endl;
T<3>::xType a3;
cout << typeid(a3).name() << endl;
return 0;
}
There is a particular line in the code which doesn't compile:
typedef T3::xType xType;
If I remove this line, compilation goes fine and the result is:
char
long
float
If I retain this line, compilation errors are observed.
main.cpp(53) : warning C4346: 'T<x>::xType' : dependent name is not a type
prefix with 'typename' to indicate a type
main.cpp(54) : see reference to class template instantiation 'T2<r>' being compiled
main.cpp(53) : error C2146: syntax error : missing ';' before identifier 'xType'
main.cpp(53) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
I am not able to figure out how to make sure that T::xType can be treated as a type inside the T2 template. Any help is highly appreciated.
Since T3 in your template class depends on the template parameter, the compiler can't known for sure what T3::xType will refer to (that might depend on the actual type r in each instantiation T2<r>).
To tell the compiler that T3::xType will be a type, you need to add the typename keyword:
typedef typename T3::xType xType;
Try
typedef typename T3::xType xType;
The error message tells you exactly what you need to do: Add typename before the type.
typedef typename T3::xType xType;
The reason you need this is that if there's an identifier that can be treated as a variable or a type, the compiler will treat it as a variable, which is what's happening in this case. In order to let the compiler know that it's actually a type you use the typename keyword.