This question already has answers here:
When can I use a forward declaration?
(13 answers)
Closed 7 years ago.
I'm having a hard time understanding template class implementation in C++. I understand what a template class is and how to use it, but I cannot seem to implement them properly. This is for school so I cannot use standard library list/etc. I have made a template List class that acts as a linked list using a template node class. I have a third class bigInt which will be used to do infinite precision addition, multiplication, etc. For the bigInt class I get an error when trying to have a variable "values" that is of type List. Why is this? Error: "Error C2079 'bigInt::values' uses undefined class 'List'"
bigInt.h looks like:
template <typename T>
class List;
class bigInt {
public:
List<int> values;
bigInt();
bigInt add(bigInt);
bigInt mul(bigInt);
bigInt pow(int);
};
I added the first two lines because I read somewhere that I needed to use "forward declaration" (since you apparently cannot use an #include "List.h") which I also don't really understand.
Any help would be really appreciated.
You need to completely define the class List<> before you can use it as a member variable. This is usually done by defining the template class in a separate .h file and #includeing it where needed (not sure why you think you can't do this). Alternatively, you can use a pointer to a List without defining it first:
template <typename T>
class List;
class bigInt {
public:
List<int>* values;
/*...*/
}
Related
This question already has answers here:
Container of fixed dynamic size
(4 answers)
Closed 7 years ago.
Is there a C++ type that acts like a "dynamically sized non resizable array"? This kind of type can be thought of as one of two things:
vector<T> but without resize, push_back, etc.
array<T,N> but where N is dynamic and not static.
I do not want a solution that only works if the type of the elements within the array is a non-copyable type. I want a generic solution.
Yes, there (pretty much) is. std::unique_ptr<T[]>. The primary template has a partial specialisation for this case, which provides the appropriate interface (operator [], no operator * etc.)
Alternatively, you can wrap std::vector in your own class and restrict its interface. You could even do that by deriving a class from std::vector using non-public inheritance and publishing only the relevant parts of its interface:
template <class T, class A = std::allocator<T>>
struct FixedVector : private std::vector<T, A>
{
using FixedVector::vector::vector;
using FixedVector::vector::operator=;
using FixedVector::vector::get_allocator;
using FixedVector::vector::at;
using FixedVector::vector::front;
using FixedVector::vector::back;
using FixedVector::vector::data;
using FixedVector::vector::begin;
using FixedVector::vector::cbegin;
using FixedVector::vector::end;
using FixedVector::vector::cend;
using FixedVector::vector::empty;
using FixedVector::vector::size;
using FixedVector::vector::operator[];
};
This question already has answers here:
Undefined reference to static class member
(9 answers)
Closed 9 years ago.
I'm trying to initialize an array called ARRAY inside the constructor of a class called CLASS_A and this array is supposed to be accessible by the nested class CLASS_B. I thought of making the array a template but that was when things started to get a little fuzzy with how to go about the syntax.
I'm almost certain that declaring the ARRAY static is part of the solution and maybe making the type const int a template like A so then the template would look like template <class A, const int D> and the declaration A ARRAY[SIZE];. Anyways I initially got this error compiling the code below and then I made some changes and got a different error.
This is a linker error by the way
nested_class_incomplete_type.cpp|16|undefined reference to `CLASS_A<3>::ARRAY'|
nested_class_incomplete_type.cpp|28|undefined reference to `CLASS_A<3>::ARRAY'|
edit duplicate code.
You only declared ARRAY in CLASS_A, you need to define it:
template <const int D>
int CLASS_A<D>::ARRAY[SIZE] = {};
BTW, your SIZE field is redundant, you don't need it, e.g:
template <size_t N>
class CLASS_A
{
public:
static int ARRAY[N];
//.....
};
template <size_t N>
int CLASS_A<N>::ARRAY[N] = {};
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to declare a friend class conditionally?
This question branches off from Can friend class be declared conditionally in C++03?. Specifically, does C++11 provide any additional options to help with conditionally declaring a friend class? That is, is it at all possible to do this in C++11?
Going through cplusplus.com, I came across std::enable_if. I tried using it, but could not figure out the right syntax. Is std::enable_if the right construct to use for this purpose? Below is the code I tried, based on the example given there. I do not really need a template here, but I do not know how to avoid it, since all the example codes given there use it.
class Foo {
template<typename T> struct std::enable_if<true, T> {
typedef T Bar;
friend class Bar;
};
};
This gives the following compile error message:
prog.cpp:5:36: error: 'enable_if' is not a template
prog.cpp:5:55: error: qualified name does not name a class before '{' token
Edit Just to make this more easily visible, as mentioned below in the comment: This requirement is unusual. This is part of a new research project in hardware simulation, that I am working on. The testbench is written in C++, and I want to display the variables in a waveform. I have researched various other options, and figured out that I need to use a friend class, due to practical considerations. The friend will capture the values and generate the waveform, but I would prefer to have the friend only when the waveform is required, and not all the time.
[class.friend]/3 tells this :
A friend declaration that does not declare a function shall have one of the following forms:
friend elaborated-type-specifier ;
friend simple-type-specifier ;
friend typename-specifier ;
therefore it is not possible to conditionally declare friends of a class.
Actually, you can do it with a macro :
class Foo {
#ifdef DECLARE_A_FRIEND
friend class Bar;
#endif
};
};
and then define or undefine the macro as a compilation parameter.
This question already has answers here:
Restrict C++ Template Parameter to Subclass
(8 answers)
Closed 7 years ago.
Is there any way to make a template only work with child classes of a base class? Something like this:
template<BaseClass T>
class FooBar
{
// ...
};
Either use a static assert from your favourite C++ library (such as this boost example), or put a call in the constructor (or other code which will always be generated when the code is used) to a do-nothing function taking a BaseClass type, for example:
template<class T>
class FooBar
{
public:
FooBar () {
Check(static_cast<T*>(0));
}
private:
void Check ( BaseClasse* ) {}
};
(not tested)
Not directly, but you can test it in the constructor using Boost:
#include <boost/type_traits/is_base_of.hpp>
#include <boost/static_assert.hpp>
template<class T>
class FooBar{
FooBar(){
BOOST_STATIC_ASSERT(boost::is_base_of<BaseClass,T>::value);
}
};
Or if you don't want a static assert, something like this is also nice sometimes:
typedef char ERROR_T_must_be_derived_from_BaseClass[boost::is_base_of<BaseClass,T>::value ? 1 : -1];
Since whoever compiles your code will be brought to this line and has a "readable" error message.
There are ways to make it work with a static assert. See Boost.StaticAssert
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Template type deduction in C++ for Class vs Function?
When calling a template function, you don't need to specify the template parameters if they are non-ambiguous from your parameters. E.g. for:
template<typename T> T foo(T a) { /*...*/ }
You can just call foo(1) and it will work, it does not need to be foo<int>(1).
This is not true for classes/structs, even if it would be clear from the constructor parameters. For example:
template<typename T> struct Foo { Foo(T a) { /*...*/ } };
Now I cannot do just a do_something_with(Foo(1)), it must be do_something_with(Foo<int>(1)).
Often, to work around this issue, there are just some simple wrapper functions which basically just wrap the constructor. That is even in the STL: std::make_pair is such an example.
Now the question: Why is that? Is there any rational reason behind it?
As far as I know, function templates and class templates are different for the lulz and there's no real reason that they should be different from each other. Of course, class templates have partial specializations (T*) as an advantage.