Reputation: 671
I'm learning C++ and I am having trouble bringing this design pattern over from C#. I can't work out if this pattern will not work in C++ or if I just have the incorrect syntax.
In the example I want to create a class that decodes a bitset.
In C# with generics it would look something like this :
abstract class Base<T>
{
public abstract T GetValue(BitArray bits);
}
class Derived : Base<MyType>
{
public override MyType GetValue(BitArray bits)
{
// Do some magic to decode this bitset
}
}
This is my naive attempt in C++
template<T,Q>
class Base
{
public:
Base() = default;
virtual ~Base() = 0;
virtual T* GetValue(const std::bitset<Q>& bits) const = 0;
}
class Derived : Base<MyType, 32>
{
public:
Derived();
~Derived();
MyType* GetValue(const std::bitset<32>& bits) const;
}
MyType* Derived::GetValue(const std::bitset<32>)
{
// Do some magic to decode this bitset
}
The compiler throws all manner of errors when I try to compile that C++ code (which I imagine is wrong in a number of ways).
How might I achieve this pattern of having the inheriting class specify a type parameter for the template of the base in C++?
Upvotes: 0
Views: 45
Reputation: 16882
The compiler throws all manner of errors when I try to compile that C++ code (which I imagine is wrong in a number of ways).
MyType
is not definedBase
More over, it's no clear why would you have that method virtual at all. You should also perhaps return by value from Derived::GetValue
, or perhaps a smart pointer to MyType
:
unique_ptr<MyType> Derived::GetValue(const std::bitset<32> &) {...}
#include <bitset>
#include <memory>
class MyType;
template<typename T, unsigned Q>
class Base
{
public:
virtual std::unique_ptr<T> GetValue(const std::bitset<Q>& bits) const = 0;
};
class Derived : public Base<MyType, 32>
{
public:
std::unique_ptr<MyType> GetValue(const std::bitset<32>& bits) const;
};
Upvotes: 1
Reputation: 123094
No offense, but your errors are just due to a couple of more or less obvious mistakes:
;
after class declarationMyType
#incldue <bitset>
GetValue
typename
for T
Q
should be a size_t
Fixing those it compiles:
#include <iostream>
#include <bitset> //
using namespace std;
struct MyType{}; //
template<typename T,size_t Q> //
class Base
{
public:
Base() = default;
virtual ~Base() = 0;
virtual T* GetValue(const std::bitset<Q>& bits) const = 0;
}; //
class Derived : Base<MyType, 32>
{
public:
Derived();
~Derived();
MyType* GetValue(const std::bitset<32>& bits) const;
}; //
MyType* Derived::GetValue(const std::bitset<32>&) const //
{
// Do some magic to decode this bitset
}
int main() {
// your code goes here
return 0;
}
Upvotes: 0
Reputation: 169281
You have multiple errors:
template<T,Q> // Wrong
template<typename T, std::size_t Q> // Fixed
MyType* Derived::GetValue(const std::bitset<32>) // Wrong
MyType* Derived::GetValue(const std::bitset<32> &) const // Fixed
You also need a semicolon following a class declaration, so the }
character that follows each class declaration needs to be };
.
After making those changes (and forward-declaring MyType
, which I assume already is declared in your code), the code compiles.
Upvotes: 0