I have a header file,
class CListEx
{
public:
CListEx();
~CListEx();
void InitList();
void AddList(char * msg);
private:
template <typename T>
struct MyList {
T data;
int num;
};
};
Now in Cpp file,
void CListEx::InitList()
{
MyList *my = new MyList();
}
And this gives error,
E0441 argument list for class template "CListEx::MyList" is missing
Error C2514 'CListEx::MyList': class has no constructors
Any ideas?
What I TRIED:
I tried below approach and that also gives errors.
template <typename T >MyList *my = new template <typename T >MyList();
The error message gives a very clear reason: argument list for class template is missing. Meaning, you should write some code like:
void CListEx::InitList()
{
MyList<int> *my = new MyList<int>();
}
Read up on templates for example at: https://www.programiz.com/cpp-programming/templates
Is this what you are trying to do?
class CListEx
{
public:
template <typename T>
void InitList();
private:
template <typename T>
struct MyList {
T data;
int num;
};
};
template <typename T>
void CListEx::InitList()
{
MyList<T> *my = new MyList<T>();
}
int main()
{
CListEx cle;
cle.InitList<int>();
}
Or are you trying to do this?
template <typename T>
class CListEx
{
public:
void InitList();
private:
struct MyList {
T data;
int num;
};
};
template <typename T>
void CListEx<T>::InitList()
{
MyList *my = new MyList();
}
int main()
{
CListEx<int> cle;
cle.InitList();
}
Beware of the memory leak. Preferably use std::unique_prt from <memory>.
Related
How can I create a functor (in templates) that get void or int
template <class T>
Int TEMP::operator()(T s)
{
...
}
Thanks
Probably by not using templates:
template<class T> int TEMP<T>::operator()(int s)
{
...
}
template<class T> int TEMP<T>::operator()()
{
...
}
I'm sure there is a very easy answer, but I can't figure it out. I have written a templated class, but I want to pass that class by reference in a class function that isn't templated. Heres what I have. I get a bunch of errors. All I need to do is figure how to format the way to insert templated class into function, but I'm at a lost. Thank you and sorry if the code doesn't really help you out.
#include <iostream>
using namespace std;
template <typename T>
class Foo {
public:
Foo();
insert(const T& Item)
//And other function, just examples
};
class noFoo(){
void test(Foo <T>& foo);
int i;
int j;
int k
};
template <typename T>
void noFoo::test(Food <T>& foo)}
cout << "hi";
}
int main() {
Foo<char> wr;
test(wr);
return 0;
}
Make test a function template. I also corrected loads of syntax errors for you (class noFoo()?), removed unnecessary code, and ran clang-format for indentation.
#include <iostream>
template <typename T>
class Foo {};
class noFoo
{
public:
template <typename T>
void test(Foo<T> &);
};
template <typename T>
void noFoo::test(Foo<T> &)
{
std::cout << "hi\n";
}
int main()
{
Foo<char> wr;
noFoo{}.test(wr);
}
Since your question is tagged d, here the same code in D.
import std.stdio;
class Foo(T) {};
class noFoo
{
public:
void test(T)(Foo!(T))
{
writeln("hi");
}
};
void main()
{
auto wr = new Foo!char;
(new noFoo).test(wr);
}
I wonder whether the below tricky situation is possible:
Suppose I have a template class template <typename DTYPE> class A{};, where DTYPE is supposed to be one of uint8_t, uint16_t, etc. I want to add a friend class to A, but this friend class differs for each DTYPE alternative. Further, suppose the friend classes for different DTYPE values are not instantiations of another template class, but independent classes.
Is there a way to do it?
You can add template "proxy" class FriendOfA and specialize it for whatever type you need:
// actual friends
class FriendUint8 {};
class FriendUint16 {};
template<typename T> struct FriendOfA;
template<>
struct FriendOfA<uint8_t> {
typedef FriendUint8 type;
};
template<>
struct FriendOfA<uint16_t> {
typedef FriendUint16 type;
};
// optional helper
template <typename T>
using FriendOfA_t = typename FriendOfA<T>::type;
template<class T>
class A {
friend typename FriendOfA<T>::type;
// or simply
friend FriendOfA_t<T>;
};
I believe you're looking for something like that:
#include <iostream>
struct BaseFriend
{
template <typename T>
void boo(const T& t) { t.foo(); }
};
struct BaseFriendProxy
{
template <typename T>
void boo(const T& t) { std::cout << "Proxy: "; t.foo(); }
};
template <typename TType>
struct Friend ;
template <>
struct Friend<int> {
using T = BaseFriend;
};
template <>
struct Friend<char> {
using T = BaseFriendProxy;
};
template <typename DTYPE>
class A
{
private:
friend typename Friend<DTYPE>::T;
void foo() const
{ std::cout << "A::foo()" << std::endl; }
};
int main()
{
A<int> a;
BaseFriend bf1;
bf1.boo(a);
A<char> b;
BaseFriendProxy bf2;
bf2.boo(b);
return 0;
}
But this will work only with C++11: you can't combine friend class ... with typename X::Y in C++03
Sure you can, specialize your template and add whatever friend class you want:
#include <iostream>
using namespace std;
class base {
public:
virtual int getValue() = 0;
};
class friend1 {
public:
base* ptr;
int getValue() {
return ptr->getValue();
}
};
class friend2 {
public:
base* ptr;
int getValue() {
return ptr->getValue();
}
};
template <typename DTYPE> class A : public base{
public:
A() { data = 42; }
// No friends
private:
int data;
int getValue() {
return data;
}
};
template <> class A<char> : public base{
public:
A() { data = 44; }
friend class friend1;
private:
int data;
int getValue() {
return data;
}
};
template <> class A<bool> : public base{
public:
A() { data = 45; }
friend class friend2;
private:
int data;
int getValue() {
return data;
}
};
int main()
{
A<char> obj1;
friend1 friend_of_obj1;
friend_of_obj1.ptr = &obj1;
cout << friend_of_obj1.getValue() << endl;
A<bool> obj2;
friend2 friend_of_obj2;
friend_of_obj2.ptr = &obj2;
cout << friend_of_obj2.getValue();
}
http://ideone.com/hM9x0y
Yes, a friend can be based on a template. Such as;
template <typename DTYPE>
struct Friend;
template <class DTYPE>
class A {
friend struct Friend<DTYPE>;
};
For each type DTYPE for the class A you wish to support (different by implementation) you can specialise Friend, such as;
template<>
struct Friend<uint8_t> {
// ...
};
A basic working sample:
#include <cstdint>
using namespace std;
template<typename T>
struct Friend;
template <class T>
class A {
friend struct Friend<T>;
int i = 0;
};
template<>
struct Friend<uint8_t> {
void method() {
A<uint8_t> a;
a.i = 8;
}
};
template<>
struct Friend<uint16_t> {
void method() {
A<uint16_t> a;
//A<uint8_t> b; // fails to compile
a.i = 16;
}
};
int main()
{
A<uint8_t> a;
Friend<uint8_t> f;
f.method();
}
Suppose I have a template class:
template<typename T>
struct Node
{
T val;
Node *next;
};
template<typename T>
class MyClass
{
T data1_;
T data2_;
vector<Node<T> > vi_;
};
Now I want to serialize MyClass to disk using different method. For example, using raw c system call write/read or c++ fstream , or other approach.
I introduce another template parameter to do that:
template<typename T,typename SerializerTrait>
class MyClass
{
T data1_;
T data2_;
vector<Node<T> > vi_;
void save()
{
SerializerTrait::save(data1_);
SerializerTrait::save(data2_);
SerializerTrait::save(vi_);
}
};
//serializer
template <typename>
class RawC
{
static FILE *f;
static void save(T t){fwrite(&t,sizeof(t),1,f);}
...
}
template <typename>
class StreamCPP
{
static fstream *f;
static void save(T t){*f<<t);}
...
}
It can work. But it seems not elegant.
Strategy pattern is a good solution, but template function cannot be virtual.
Is there any better way to do that?
You can do something like this:
template<typename T>
class MyClass
{
template <class SERIALIZER>
void save()
{
SERIALIZER::save(data1_);
SERIALIZER::save(data2_);
SERIALIZER::save(vi_);
}
//or with serializer instance
template <class SERIALIZER>
void save(SERIALIZER & s)
{
s.save(data1_);
s.save(data2_);
s.save(vi_);
}
virtual void save(SerializerDetail * s)
{
s->save(this);
}
};
class SerializerDetail
{
public:
template <class T>
void save(T * p)
{
p->save<SomeSerializer>();//use the first two save functions
//or
p->save(SerializerInstance);//or this of you want it
}
};
Consider the following design :
template <class SecondType>
struct First
{
SecondType* _ptr;
};
template <class FirstType>
struct Second
{
FirstType* _ptr;
};
where the First type has a pointer to a Second type and vice-versa. The problem is that I cannot declare this because they are interdependent and I should declare First<Second<First<Second...>>>.
How to solve this problem ?
Maybe a work-around with something that looks like CRTP but even crazier:
#include <iostream>
template <class SecondType>
struct FirstBase
{
SecondType* _ptr;
};
template <class FirstType>
struct SecondBase
{
FirstType* _ptr;
};
struct FirstDerived
: public FirstBase<SecondBase<FirstDerived>>
{
};
struct SecondDerived
: public SecondBase<FirstBase<SecondDerived>>
{
};
int main()
{
FirstBase<SecondDerived> x;
SecondBase<FirstDerived> y;
return 0;
}
If someone has a more elegant way to do this, I would be happy to see it.
Not sure what you are trying to achieve but the following compiles fine.
template <class T> struct First { T* _ptr; };
template <class T> struct Second { T* _ptr; };
int main(){
First<Second<First<Second<void>>>> a; // or
First<Second<First<Second<nullptr_t>>>> b;
return 0;
}
Note I replaced FirstType, SecondType altogether cos it does not matter. T would be replaced by whatever you pass and this will happen when the template is being specialized before compilation.
Here is another possibly more elegant solution which doesn't require void at all. I don't know if the inheritance is acceptable to you but I think it works well.
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
struct Base {
//make all functions virtual
};
template <class SecondType>
struct First: public Base
{
SecondType* _ptr;
First(SecondType * st) {
_ptr = st;
}
First() {
}
};
template <class FirstType>
struct Second: public Base
{
FirstType* _ptr;
Second(FirstType * ft) {
_ptr = ft;
}
Second() {
}
};
int main() {
First<Base> f;
Second<Base> s;
f._ptr = &s;
s._ptr = &f;
cout << s._ptr << endl;
}