picklesmithy129
picklesmithy129

Reputation: 81

Simpilfy two function calls with same parameters in C++ 11

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

Answers (2)

Peter
Peter

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

perivesta
perivesta

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

Related Questions