Creating an instance of templated abstract class - c++

I would like to instantiate a templated abstract class, like the following one:
template <class T>
class non_sense {
public:
void virtual nonsesnse_func() = 0;
};
to make an integer instance of this class I tried the following:
void non_sense<int>::nonsesnse_func(){
}
and then I make my instance in main :
non_sense<int> xx;
so the whole program is as follow:
template <class T>
class non_sense {
public:
void virtual nonsesnse_func() = 0;
};
void non_sense<int>::nonsesnse_func(){
}
void main(){
non_sense<int> xx;
}
It totally make sense to me, the compiler doesn't accept it though, saying the class is abstract. I don't want to take the route of creating a new class inheriting from this class using a specific template, regarding the big application I am trying to make this will be massive writting. Can somebody explain to me why the compiler rejects this, and is there any way arround this apart from creating a new class for the specific instance I want.

non_sense is an abstract class, so it can never be instantiated into an object.
This compiles and runs, however:
#include <iostream>
template <class T>
class non_sense {
public:
virtual void nonsesnse_func();
};
// Specialize the method
template<>
void non_sense<int>::nonsesnse_func(){
std::cout << "no_sense<int>::nonsense_func" << std::endl;
}
int main(){
non_sense<int> xx;
xx.nonsesnse_func();
return 0;
}
And here's code showing how to make this run with a pure abstract class (I've renamed nosnsnsense to nonsense, it's easier to type ;) :
#include <iostream>
template <class T>
class non_sense {
public:
virtual void nonsense_func() = 0;
};
template<class T>
class non_sense_concrete : public non_sense<T> {
public:
void nonsense_func() {
std::cout << "non_sense_concrete<T> generic code" << std::endl;
}
};
// Specialize the concrete class
template<>
void non_sense_concrete<int>::nonsense_func(){
std::cout << "no_sense<int>::nonsense_func" << std::endl;
}
int main(){
non_sense_concrete<double> objectGeneric;
objectGeneric.nonsense_func();
non_sense_concrete<int> objectInt;
objectInt.nonsense_func();
return 0;
}

Odd as it might seem, pure virtual methods can have an implementation in C++. That does not change the fact that the method is pure virtual and the class containing it is abstract.
If you want the class non_sense to be abstact for all types except int, you will have to provide a specialisation for the entire class, not just for the pure virtual members:
template <class T>
class non_sense {
public:
virtual void nonsense_func() = 0;
};
template <>
class non_sense<int> {
public:
virtual void nonsense_func()
{
std::cout << "no_sense<int>::nonsense_func" << std::endl;
}
};
With a larger class, inheritance would probably be easier, because then the derived class can inherit the other members from non_sense, instead of having to duplicate the entire class (as you need to do when creating a specialisation).

If you have an class with a pure virtual function (i.e. abstract) you MUST create a second class that implements that virtual function. Otherwise you will never be able to use that class.
In your code you implemented a function alright, but it's not virtual because it is not inside of a class. It needs to be declared and defined as part of a sub-class off of non_sense in order to work. Please keep in mind that only classes can have virtual functions.

Related

When using template and inheritance together, I do not know how to override a member function

I have the following code that mixes template and inheritance.
Class Base has some utility function to build items (the work in the sample code), and Child call the work in its implementation of the API call.
In this function
virtual void call() override {
Base<T>::work(); // Problem Here
// work();
}
I try to call work() but got the following error:
test.cc: In member function ‘virtual void Child<T>::call()’:
test.cc:18:2: error: there are no arguments to ‘work’ that depend on a template parameter, so a declaration of ‘work’ must be available [-fpermissive]
So I write Base<T>::work() and makes it work.
Now I have a Grandson class, who want to override the work function. But the override does not work as in Child<T>::call I have explicitly specified calling Base<T>::work(). So what's the correct way to implement Child<T>::call to make the override in Grandson work?
#include <iostream>
template <typename T>
class Base {
protected:
virtual void work() {
T a;
std::cout << "From Base" << '\n';
}
public:
virtual void call() = 0;
};
template <typename T>
class Child : public Base<T> {
public:
virtual void call() override {
Base<T>::work(); // Problem Here
// work();
}
};
template <typename T>
class Grandson : public Child<T> {
protected:
void work() override {
std::cout << "From Grandson" << '\n';
}
};
int main() {
Grandson<int> g;
g.call();
}
Replace Base<T>::work() with this->work().
When you are a template class inheriting from a base class dependent on your template parameter, the compiler doesn't look into your base when it sees something like work(). Instead, you have to tell it that it needs to do that. The easiest way I know of to accomplish that is to prefix the call with this->.
As for why it does not work when you use Base<T>::work(), I am not entirely sure. It's hardcoding it to call the base class implementation, but I'm fairly sure there's a similar syntax that does work.

Arrays of template class objects

Problem
I would like an array of pointers to instances of a template class. My problem would be solved if C++ allowed templated virtual methods in a base class, with a templated derived class.
Therefore, how would one implement templated virtual methods?
Below I have a solution which seems to work, but I'm interested in comments about my implementation.
Constraints
The template parameter is infinitely variable, e.g., I cannot enumerate every specialization of this template class. The template class T can be any POD, array of POD, or struct of POD.
The complete set of T is known at compile time. Basically, I have a file which defines all the different T used to instantiate the objects, and use Xmacros (https://en.wikipedia.org/wiki/X_Macro) to create the array of objects.
I know this isn't a great idea. Let's gloss over that for the time being. This ends up being more a curiosity.
Possible Solutions
These are the things I've looked into.
Create base and derived classes
class Base {
virtual void SomeMethod() = 0;
}
template <class T>
class Derived : Base {
void SomeMethod() {...}
}
The problem with this is I cannot declare all the virtual methods in Base that I want to overload, as virtual methods cannot be templated. Otherwise, it would be a perfect solution.
std::any/std::variant
I am using C++17, so I could define the virtual base methods taking std::any. But it cannot hold arrays, which precludes its use here.
CRTP
It seems this would not help me create an array of these different objects. I would need to do something like
template <typename D, typename T>
class Base
{
...
};
template <typename T>
class Derived : public Base<Derived, T>
{
...
};
So I still end up with trying to create an array of Derived<T> objects.
Visitor Pattern
Again it looks like I would need to enumerate every possible type the Visitable class needs to service, which, while not impossible (again, I have a file which defines all the different T that will be used) seems like more Xmacros, which is just making the problem more complicated.
My Solution
This is what I came up with. It will run in https://www.onlinegdb.com/online_c++_compiler
#include <iostream>
#include <array>
#include <typeinfo>
// Base class which declares "overloaded" methods without implementation
class Base {
public:
template <class T>
void Set(T inval);
template <class T>
void Get(T* retval);
virtual void Print() = 0;
};
// Template class which implements the overloaded methods
template <class T>
class Derived : public Base {
public:
void Set(T inval) {
storage = inval;
}
void Get(T* retval) {
*retval = storage;
}
void Print() {
std::cout << "This variable is type " << typeid(T).name() <<
", value: " << storage << std::endl;
}
private:
T storage = {};
};
// Manually pointing base overloads to template methods
template <class T> void Base::Set(T inval) {
static_cast<Derived<T>*>(this)->Set(inval);
}
template <class T> void Base::Get(T* retval) {
std::cout << "CALLED THROUGH BASE!" << std::endl;
static_cast<Derived<T>*>(this)->Get(retval);
}
int main()
{
// Two new objects
Derived<int>* ptr_int = new Derived<int>();
Derived<double>* ptr_dbl = new Derived<double>();
// Base pointer array
std::array<Base*, 2> ptr_arr;
ptr_arr[0] = ptr_int;
ptr_arr[1] = ptr_dbl;
// Load values into objects through calls to Base methods
ptr_arr[0]->Set(3);
ptr_arr[1]->Set(3.14);
// Call true virtual Print() method
for (auto& ptr : ptr_arr) ptr->Print();
// Read out the values
int var_int;
double var_dbl;
std::cout << "First calling Get() method through true pointer." << std::endl;
ptr_int->Get(&var_int);
ptr_dbl->Get(&var_dbl);
std::cout << "Direct values: " << var_int << ", " << var_dbl << std::endl;
std::cout << "Now calling Get() method through base pointer." << std::endl;
ptr_arr[0]->Get(&var_int);
ptr_arr[1]->Get(&var_dbl);
std::cout << "Base values: " << var_int << ", " << var_dbl << std::endl;
return 0;
}
When this is run, it shows that calling the methods on Base correctly point to the Derived implementations.
This variable is type i, value: 3
This variable is type d, value: 3.14
First calling Get() method through true pointer.
Direct values: 3, 3.14
Now calling Get() method through base pointer.
CALLED THROUGH BASE!
CALLED THROUGH BASE!
Base values: 3, 3.14
Essentially I am manually creating the virtual method pointers. But, since I am explicitly doing so, I am allowed to use template methods in Base which point to the methods in Derived. It is more prone to error, as for example for each template method I need to type the method name twice, i.e., I could mess up:
template <class T> void Base::BLAH_SOMETHING(T inval) {
static_cast<Derived<T>*>(this)->WHOOPS_WRONG_CALL(inval);
}
So after all this, is this a terrible idea? To me it seems to achieve my objective of circumventing the limitation of templated virtual methods. Is there something really wrong with this? I understand there could be ways to structure the code that make all this unnecessary, I am just focusing on this specific construction.
It is more prone to error, as for example for each template method I need to type the method name twice
Oh, that's the least of your concerns. Imagine if you downcast to the wrong type.
At least save yourself a headache and use dynamic_cast:
class Base {
public:
virtual ~Base() = default;
template <class T>
void Set(T inval) {
dynamic_cast<Derived<T>&>(*this).Set(inval);
}
template <class T>
T Get() {
return dynamic_cast<Derived<T>&>(*this).Get();
}
};
template <class T>
class Derived : public Base {
public:
void Set(T inval) {
storage = inval;
}
T Get() {
return storage;
}
private:
T storage{};
};
Other than that, I agree with the comments, this is probably not the right approach to your problem.
The normal run-off-the-mill method of dealing with subclasses that contain unknown types is to move the entire thing to a virtual function. Thus, instead of
superclass->get_value(&variable_of_unknown_type);
print(variable_of_unknown_type);
you write
superclass->print_value();
Now you don't need to know about any of the types a subclass might contain.
This is not always appropriate though, because there could be lots of operations. Making every operation a virtual function is troublesome if you are adding new operations all the time. On the other hand, the set of possible subclasses is often limited. In this case your best bet is the Visitor. Visitor rotates the inheritance hierarchy 90°, so to speak. Instead of fixing the set of operations and adding new subclasses freely, you fix the set of subclasses and add new operations freely. So instead of
superclass->print_value();
you write
class PrinterVisitor : public MyVisitor
{
virtual void processSubclass1(Subclass1* s) { print(s->double_value); }
virtual void processSubclass2(Subclass2* s) { print(s->int_value); }
};
superclass->accept(PrinterVisitor());
Now accept is the only virtual function in your base class. Note there are no casts that could possibly fail anywhere in the code.

Trying to point a base class function pointer to a derived class function

I'm trying to implement a strategy pattern. Right now I'm making a vector of function pointers that take in a vector of ints as their type. I called this vector of function pointers "algo". I want each of the function pointers in the vector to point to a different sorting class (merge, bubble, or insertion). My class structure looks like this: Algorithm is the base class, Sort is an abstract class that inherits from Algorithm, and then Merger, Insertion, and Bubble all inherit from Sort. The problem that I'm running into right now is I can't seem to get my mergePointer pointed to the sortFunc() inside the Merger class. When I try to execute my code it says:
main.cpp:59:28: error: use of undeclared identifier 'sortFunc'
mergePointer = sortFunc();
^
I originally figured the problem was scope resolution so I added Merger:: infront of sortFunc() and I got the same error. I'm not to familiar with polymorphism and am not even sure if what I'm trying to do is possible, any thoughts?
class Algorithm{
private:
public:
vector<int> data;
static std::vector<void (*)(std::vector<int>&)> algo;
void (*activeAlgo)(std::vector<int>&);
enum SortingAlgorithms{
Merge = 0, Insertion, Bubble, Last
};
void load(){
void (*mergePointer)(vector<int>&);
mergePointer = sortFunc();
algo.push_back(mergePointer);
}
void select(SortingAlgorithms sort){
}
};
//abstracted class
class Sort: public Algorithm{
private:
public:
virtual void sortFunc() = 0; //pure virtual function
};
class Merger: public Sort{
private:
public:
void sortFunc(){
data = mergeSort(data);
print(data);
}
};
class Insertion: public Sort{
private:
public:
void sortFunc(){
printVec(data);
insertionSort(data);
printVec(data);
}
};
class Bubble: public Sort{
private:
public:
void sortFunc(){
printVector(data);
bubbleSort(data);
printVector(data);
}
};
int main(){
Sort *myAlgo;
myAlgo->select(Algorithm::Bubble);
}
Note that void(*)(std::vector<int>&) can point only to a namespace function or to static member. Pointers to members are class-specific and have to be called with special operator .* or ->*. What you may implement, is a CRTP with virtual base class (stripped of static vector and other bells and whistles for brevity):
#include <iostream>
#include <cstdlib>
class ActorBase
{
public:
// virtual interfaces
virtual void action() = 0;
};
template <class T>
class Actor : public ActorBase
{
protected:
typedef void(T::* FuncPtr)(/* params */);
FuncPtr algo;
public:
void action()
{
/* do call algo for appropriate object by treating this as pointer to T */
(dynamic_cast<T*>(this)->*algo)(/* args */);
}
};
class Concrete : public Actor<Concrete>
{
void bar() { std::cout << "Hello, Concrete!" << std::endl; }
public:
Concrete() { algo = &Concrete::bar; }
};
int main()
{
Concrete a;
a.action();
return EXIT_SUCCESS;
}
Curiously Recurrent Template Actor is very special template which can cast pointer to self to derived class. Still, it can't know anything about Concrete, e.g. typedefs or members. If it required to pass some traits like that, Actor Should be derived from a template class specialized for concrete T, known as trait class.
Not sure that this perverted approach is what actually needed to solve your X problem though, but at least it's syntactically correct. Here is a canonical CRTP.
Note that the call by member pointer requires .* \ -> AND parenthesis, because call operator () got higher priority than .*.

Calling a virtual function on all classes inheriting from a given superclass

I'm trying to implement user defaults in my C++ app.
For that I created an interface class with one function in it:
class IRegisterUserDefaults
{
public:
IRegisterUserDefaults();
virtual void registerUserDefaults(){}
};
Each class inheriting from this interface class will implement the function to register the user defaults it needs to be set.
So far no problem. But what's the best way of calling it?
I'm coming from Objective-C where I could just search through all classes and find the ones who implement the interface and call the registerUserDefaults function on them. I understand though that C++ doesn't have this level of introspection. It would be sufficient to call the function once per class (and thus make it static).
Objective
It would be great if the function would be called "automatically" if a class subclasses IRegisterUserDefaults. I tried calling the method from the IRegisterUserDefaults constructor but it looks like this doesn't call the subclass function properly. Is there a way to make this happen?
Also, what would be best way to make sure this is only called once per class?
IRegisterUserDefaults is not a meaningful interface, in any language.
It sounds like the actual problem you are trying to solve is "run some code once, at or near class first use". You can do that with something like this
class HasUserDefaults {
static std::once_flag register_once;
void registerUserDefaults() { /*...*/ }
public:
HasUserDefaults ()
{
// in all the constructors
std::call_once(register_once, &HasUserDefaults::registerUserDefaults, this);
}
// other members
};
Do you have a single location where all those derived classes are known? In that case, do it there:
// The type-list can be used in many ways, as you need
using all_classes = std::tuple<A, B, C, D /* and so on */>;
template <class... Ts>
static void register_all_classes(Y<Ts...>*)
{ ((Ts().registerUserDefaults()), ...); }
register_all_classes((all_classes*)nullptr);
Otherwise, you must obviously go decentralized:
Do you have a single compilation-unit responsible for registering each class? In that case, use a namespace-scope object. Maybe use a helper for that:
template <class T>
struct Init {
Init() { T().registerUserDefaults(); }
};
// Used in single TU as:
static Init<SomeRegisterUserDefaults> _;
Otherwise, take a look at std::ios_base::Init how <iostream> does it. I simplified because there was no need for uninit indicated:
template <class T>
struct MultiInit {
MultiInit() { static Init<T> _; }
};
// Used in any number of TUs as:
static MultiInit<SomeRegisterUserDefaults> _;
Does this work for you?
#include <iostream>
#include <string>
class IRegisterUserDefaults
{
public:
IRegisterUserDefaults() {}
virtual void registerUserDefaults() = 0;
};
class MoreDerivedRegisterUserDefaults : public IRegisterUserDefaults
{
public:
MoreDerivedRegisterUserDefaults (int x, int y) : m_x (x), m_y (y) { }
virtual void registerUserDefaults() override {
std::cout << "MoreDerivedRegisterUserDefaults::registerUserDefaults called (" << m_x << ", " << m_y << ")" << std::endl;
}
private:
int m_x, m_y;
};
template <class T, typename... Args> void RegisterDefaultsHandler (Args... args) {
T obj (args...);
obj.registerUserDefaults ();
}
int main ()
{
RegisterDefaultsHandler<DerivedRegisterUserDefaults> ();
RegisterDefaultsHandler<MoreDerivedRegisterUserDefaults> (1, 2);
// ...
}
You have to instantiate each derived class somewhere.
Live demo (updated). Output:
DerivedRegisterUserDefaults::registerUserDefaults called
MoreDerivedRegisterUserDefaults::registerUserDefaults called (1, 2)
EDIT: After talking to #Caleth, I tweaked the code a little to make my intentions clearer.
EDIT 2: Variadiac template added, turned out to be easier than I thought, useful 'howto' guide here.
Call the method in sub-class constructor, you cannot call this in base class constructor as the sub class is not yet constructed by then.

Calling templated function of a nested class of derived class out of a nested class of a base class

I wasn't sure about a proper title. It does seem confusing. Sorry for that.
I am not a programmer. So please, bear with me. I am surely using some terminology wrongly.
Here's what I want to achieve:
Have a base class A_base with some nested class (sub-class?) defined in it (B_base). A_base will have all kinds of common functions that do not require specialization. The nested class is providing some interface for communication with another application (there are callbacks in it, which I define according to my needs).
class A_base
{
public:
void a_function()
{
std::cout << "This is a base a_function\n" ;
}
void a_b_function();
class B_base
{
public:
void b_function()
{
std::cout << "This is a base b_function\n" ;
}
void b_a_function();
virtual void b_c_function1(){return;};
virtual void b_c_function2(){return;};
B_base(const std::string& name_in, A_base* ptr_A_in):
name(name_in), ptr_A(ptr_A_in)
{}
protected:
const std::string name;
A_base* ptr_A;
};
B_base* b_object;
A_base(const std::string& name_in):
b_object(new B_base(name_in, this)), name(name_in)
{}
protected:
const std::string name;
};
void A_base::a_b_function()
{
b_object->b_function();
}
void A_base::B_base::b_a_function()
{
ptr_A->a_function();
}
Derive a templated class out of A_base (A_derived) with some additional specialized functionality and another nested class in it (C_class, which is also templated). I chose this to optimize the latency of my program. It doesn't have to be always lightning fast, but there's one particular path in the logic that must be as fast as possible. Therefore, I am trying to eliminate unnecessary branching by using templates.
enum Side{BB=0,SS=1};
template<bool B>
class A_derived : public A_base
{
public:
void a_function()
{
std::cout << "This is a derived a_function\n" ;
}
template<Side S>
class C_class
{
public:
void c_function();
C_class(const std::string& name_in, A_derived* ptr_A_in):
name(name_in), ptr_A(ptr_A_in)
{}
protected:
const std::string name;
A_derived* ptr_A;
};
C_class<Side::BB> c_object_bb;
C_class<Side::SS> c_object_ss;
A_derived(const std::string& name_in):
A_base(name_in), c_object_bb(name_in, this), c_object_ss(name_in, this)
{}
};
Here I am defining the specialized functions (the ones that are supposed to be fast):
template<> template<>
void A_derived<false>::C_class<Side::BB>::c_function()
{
std::cout << "This is a false-BB c_function\n" ;
}
template<> template<>
void A_derived<false>::C_class<Side::SS>::c_function()
{
std::cout << "This is a false-SS c_function\n" ;
}
template<> template<>
void A_derived<true>::C_class<Side::BB>::c_function()
{
std::cout << "This is a true-BB c_function\n" ;
}
template<> template<>
void A_derived<true>::C_class<Side::SS>::c_function()
{
std::cout << "This is a true-SS c_function\n" ;
}
And on top of that there's a need to be able to call some of the specialized functions out of a method of a nested class B_base. The specialized functions belong to a C_class. Hence, B_base knows nothing about it. But I am trying to circumvent this by casting the A_base pointer into A_derived pointer. I know for sure what kind of A_derived will be used in each case.
The problem is, the C_class function has to be called depending on the version of A_derived that is used. But B_base itself is not a templated class. So, clearly the following is not working the way I want it to work:
void A_derived<false>::B_base::b_c_function1()
{
static_cast<A_derived<false>*>(ptr_A)->c_object_bb.c_function();
}
void A_derived<false>::B_base::b_c_function2()
{
static_cast<A_derived<false>*>(ptr_A)->c_object_ss.c_function();
}
void A_derived<true>::B_base::b_c_function1()
{
static_cast<A_derived<true>*>(ptr_A)->c_object_bb.c_function();
}
void A_derived<true>::B_base::b_c_function2()
{
static_cast<A_derived<true>*>(ptr_A)->c_object_ss.c_function();
}
It just complains about redefining functions. And if I add template<> syntaxis it complains that there is not template out there. And it's kinda true. Can't blame the compiler for this.
Can you please suggest me a reasonable solution? How can I call a templated function of a nested class of a derived class from a method of a nested class of a base class?
Thank you.
Added: So, one person suggested in the comments I should use virtual functions instead. After some thinking I decided to clarify. B_base has its functions as virtual, actually. And this is not my code. I just have to deal with it. The reason virtual functions are of little help is that I cannot simply derive my A_base off B_base (due to some reasons). And for the most of B_base's functions I am fine with some common definitions. However, there are 10% of B_base's functions that I want to be specialized, depending on A_derived that is being instantiated.
My back up solution is to not use B_base at all but rather have some derived B_derived that'd be fully defined inside my A_derived. Unfortunately that would mean writing an infinite amount of useless code. Because most of B_base functions do not depend on type of A_derived.