Reputation: 81
The following code resembles my real application. I have a class definition that highly relies on the int value s
, when calling the instances of two classes with two different s
values, I need to write the function calling twice, do we have a simpler method like using rightInst = std::conditional_t<use10, instA, instB>;
that we used before instantiation.
template<int s>
class classAdef{
public:
// some code related to 's'
classAdef(){
// some code related to 's'
}
int operator(int a, int b, int c){
// some code related to 's'
printf("class is called \n");
return 0;
}
}
bool use10 = true;
using def10 = classAdef<10>;
using def100 = classAdef<100>;
def10 instA;
def100 instB;
if (use10){
instA(1, 2, 3);
} else{
instB(1, 2, 3);
}
// this code doesnot work, but want something like this to simpilify the function calling
using rightInst = std::conditional_t<use10, instA, instB>;
rightInst(1, 2, 3);
Upvotes: 0
Views: 86
Reputation: 36617
Polymorphism is an option here, since nothing prevents a templated class from having a polymorphic base and overriding inherited virtuals;
For example
#include <iostream>
#include <memory>
class Base
{
public:
Base() {};
virtual int operator()(int a, int b, int c) = 0;
virtual ~Base() {};
};
template<int s> class classAdef : public Base
{
public:
int operator()(int a, int b, int c)
{
// some code related to 's'
std::cout << s << " class is called \n";
return 0;
};
};
int main()
{
bool use10 = true;
std::unique_ptr<Base> object;
if (use10)
object = std::make_unique<classAdef<10> >();
else
object = std::make_unique<classAdef<100> >();
(*object)(1,2,3);
}
All the logic in deciding which overload to call is settled in the process of instantiating the object.
Use of unique_ptr
is to simplify cleanup (destroying objects when done).
Given your description, I wouldn't futz around with operator functions - an appropriately named virtual function (called by object->virtualFun(1,2,3)
) will suffice.
Upvotes: 2
Reputation: 4031
You can store the selected instance in a std::variant
and use std::visit
to call your method. You do still need some sort of conditional (here I am using a ternary) to store the correct instance, so this does not seem a lot cleaner for this specific case.
#include <cstdio>
#include <variant>
template<int s>
class classAdef{
public:
// some code related to 's'
classAdef(){
// some code related to 's'
}
int operator()(int a, int b, int c){
// some code related to 's'
printf("class %d is called \n", s);
return 0;
}
};
int main()
{
bool use10 = true;
using def10 = classAdef<10>;
using def100 = classAdef<100>;
def10 instA;
def100 instB;
std::variant<def10, def100> var;
use10 ? var = instA : var = instB;
std::visit([](auto& inst){ inst(1,2,3); }, var);
}
https://godbolt.org/z/o9n9jb7eh
Upvotes: 2