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.
Related
I'm trying to implement the following code, but I keep getting an error because of typedef, can someone please help?
template<class T>
struct box{
T data;
box *link;
};
typedef box* boxPtr;
the error is:
Use of class template 'box' requires template arguments
box is a class template. This means that it needs an argument whenever you instantiate it:
box<int> integerBox;
box<float> floatBox;
// etc
This is required anywhere you try to use a template class such as box. So a pointer to just a box doesn't make sense. It needs a type with it. For example:
template <class type>
using boxptr = box<type>*;
This does effectively the same thing as your typedef, but it allows you to specify he underlying template type.
Of course, if you do it this way, you will always need to specify a type when you use the pointer version:
boxptr<int> integerBoxPtr;
boxptr<float> floatBoxPtr;
// etc
Writing
template<class T>
struct box{
T data;
box *link;
typedef box<T>* boxPtr;
};
with
int main()
{
box<int>::boxPtr use_of_a_bad_idea;
}
is one way, but having pointer types masquerading as object types is a recipe for memory leaks: don't do it as a rule of thumb. That's the best way of addressing this problem.
Use using:
template<class T>
struct box
{
T data;
box *link;
};
template <typename T>
using boxPtr = box<T>*;
Now boxPtr<int> is the same as box<int>*.
This will compile:
template<class T>
struct Box {
T data;
Box<T> *link;
};
typedef Box<int> * BoxPTR;
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.
using c++ language : i made a structure generic and i want to give it an alias but failed !
here is the code:
template<class T>
struct noeud {
T val;
struct noeud *next;
};
typedef struct noeud * Noeud;
here is the error:
template argument required for 'struct noeud'
invalid type in declaration before ';' token
Build : 2 error(s), 0 warning(s)
you can achieve this by using a syntax introduced in the C++11 revision :
template<class T>
struct Node;
template <class T>
using NodePtr = Node<T>*;
You should stay away from naked pointer and use a smart pointer instead, like unique_ptr :
template <class T>
using NodePtr = std::unique_ptr<Node<T>>;
it should be
typedef struct noeud<your type>* Noeud;
where your type is the type you want the struct to be instanciated with
If you want to have another template as an alias you have to use the using keyword:
template<typename T>
using AliasName = noeud<T>*;
To add to the other answers:
The class noeud is a template and thus it needs a template parameter to become a type as template types are deduced at compile time. E.g.:
template<class T>
struct noeud {
T val;
//noeud* next // Error: compiler doesn't know what a noeud is.
noeud<T>* next; // Need to specify template parameter (T can be used).
};
typedef noeud<int>* Noeud; // Need to specify template parameter.
Also in C++ you don't have to put the keyword struct in front of the type when declaring "structs"/aggregate classes when there is no ambiguity. In C++ the keyword struct means class with default access specifier set to public.
As mentioned by others, in C++11 you can use the using syntax to declare a templated alias (typedef does not allow templated aliases), e.g.:
template<typename T>
using noeud<T>* Noeud; // Use 'using' to create an alias in same manner as typedef.
This allows you to use the alias as:
Noeud<int> n; // Type is: noeud<int>*
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?
I'm playing around with templates. I'm not trying to reinvent the std::vector, I'm trying to get a grasp of templateting in C++.
Can I do the following?
template <typename T>
typedef struct{
size_t x;
T *ary;
}array;
What I'm trying to do is a basic templated version of:
typedef struct{
size_t x;
int *ary;
}iArray;
It looks like it's working if I use a class instead of struct, so is it not possible with typedef structs?
The problem is you can't template a typedef, also there is no need to typedef structs in C++.
The following will do what you need
template <typename T>
struct array {
size_t x;
T *ary;
};
template <typename T>
struct array {
size_t x;
T *ary;
};
You don't need to do an explicit typedef for classes and structs. What do you need the typedef for? Further, the typedef after a template<...> is syntactically wrong. Simply use:
template <class T>
struct array {
size_t x;
T *ary;
} ;
You can template a struct as well as a class. However you can't template a typedef. So template<typename T> struct array {...}; works, but template<typename T> typedef struct {...} array; does not. Note that there is no need for the typedef trick in C++ (you can use structs without the struct modifier just fine in C++).
The Standard says (at 14/3. For the non-standard folks, the names following a class definition body (or the type in a declaration in general) are "declarators")
In a template-declaration, explicit specialization, or explicit instantiation the init-declarator-list in the dec-laration shall contain at most one declarator. When such a declaration is used to declare a class template, no declarator is permitted.
Do it like Andrey shows.
From the other answers, the problem is that you're templating a typedef. The only "way" to do this is to use a templated class; ie, basic template metaprogramming.
template<class T> class vector_Typedefs {
/*typedef*/ struct array { //The typedef isn't necessary
size_t x;
T *ary;
};
//Any other templated typedefs you need. Think of the templated class like something
// between a function and namespace.
}
//An advantage is:
template<> class vector_Typedefs<bool>
{
struct array {
//Special behavior for the binary array
}
}
The syntax is wrong. The typedef should be removed.
Looks like #monkeyking is trying it to make it more obvious code as shown below
template <typename T>
struct Array {
size_t x;
T *ary;
};
typedef Array<int> iArray;
typedef Array<float> fArray;