Reputation: 3859
I have a class which needs two separate templates passed into it:
template <typename T>
class AwesomeClass
{
TList *theList;
typename list <T>::iterator theiterator;
public:
template <typename TList>
AwesomeClass(TList &list)
{
theList = &list;
};
}
As you can probably tell it essentially provides a wrapper for the STL (I have to do it this way). Ideally I do not want to pass both templates through at object declaration like this:
typedef AwesomeClass<int, BaseClass<int> > BaseClassIteratorInt;
and would rather get away with this:
typedef BaseClass<int> ListFromBaseClassInt;
typedef AwesomeClass<int> BaseClassIteratorInt;
BaseClassIteratorInt newInt(ListFromBaseClassInt)
(This is what the above code is meant to do)
However, I keep getting the error:
error C2143: syntax error : missing ';' before '*'
For the variable TList* theList.
I would need the to ctor to provide the type for TList, is there a way to do this?
Extra steps:
Okay, I now have code of the format:
template <typename Container>
class AwesomeClass
{
public:
typedef typename std::common_type< Container > value_type;
bool firstUse;
Container *theList;
typename Container::iterator theIterator;
explicit AwesomeClass(Container &list):theList(&list)
{
};
}
This is using common_type to get around a compiler bug which stop the line
typedef typename Container::value_type value_type;
compiling due to value_type not being a part of the global namespace.
But I have a compiler error for theIterator, the compiler claims that it needs a ';' before it.
Can anyone see what is wrong?
Upvotes: 0
Views: 296
Reputation: 15524
You need to declare TList
as a template parameter before you can use it in other declarations.
template <typename TList, typename T>
class AwesomeClass {
TList* theList;
/* ... */
};
Also you don't need to declare the second template parameter T
, instead get the type like so:
using value_type = typename TList::value_type;
Secondly, you don't have to use template deduction in the ctor.
// template <typename TList> // Unnecessary if the template parameter is already declared
AwesomeClass(TList& list) {
theList = &list;
}
Thirdly, you have put the semicolon after the ctor instead of at the end of the class scope.
/* ... */
AwesomeClass(TList& list) {
theList = &list;
}; // Unnecessary to put semicolon after function definitions.
} // Although, you need semicolon here.
It looks like you want to be able to automatically deduce the types of the template parameters when creating an object of AwesomeClass
. However, class template parameters can not automatically be deduced, only function templates can do that.
To accomplish automatic deduction of template parameters you can create a function that returns a AwesomeClass
with the deduced parameters, e.g.
template <typename TList>
auto make_awesome(TList& list) -> AwesomeClass<TList, typename TList::value_type> {
return {list};
}
Edit:
If what you want is a class that stores a pointer to a std::list
of any type then all you need to deduce is the element type. But then you can only store a pointer to a std::list
container, not e.g. a pointer to std::vector
.
template <typename T>
class AwesomeClass {
public:
AwesomeClass(std::list<T>& c) {
c_ = &c;
}
private:
std::list<T>* c_;
typename std::list<T>::iterator iter_;
};
int main() {
typedef AwesomeClass<int> BaseClassIteratorInt;
BaseClassIteratorInt b{l};
}
Upvotes: 0
Reputation: 238311
I don't think you need two template params for that.
template <class Container>
class AwesomeClass {
public:
// you can use this typedef to access the value type
typedef typename Container::value_type value_type;
AwesomeClass(Container &list): theList(&list) {}
private:
Container *theList;
typename Container::iterator theiterator;
};
int main() {
// you can use typedef if you like
typedef std::list<int> intList;
intList list{1, 2, 3};
AwesomeClass<intList> newInt(list);
}
Upvotes: 1
Reputation: 217145
With
template <typename T, typename TList> class AwesomeClass
class AwesomeClass
{
TList *theList;
typename list<T>::iterator theiterator;
public:
explicit AwesomeClass(TList &list) : theList(&list) {}
};
What you can do to deduce type at construction is a free function:
template<typename T, typename TList>
AwesomeClass<T, TList> make_AwesomeClass(TList& tlist)
{
return AwesomeClass<T, TList>(tlist);
}
Call it that way:
auto awesomeClass = make_AwesomeClass<int>(mylist);
Upvotes: 0
Reputation: 4951
it sound like you need a forward declaration for TList
: you are using if before declaring it so the compiler can't know about it.
Upvotes: 0