【问题标题】:Simpilfy two function calls with same parameters in C++ 11在 C++ 11 中简化两个具有相同参数的函数调用
【发布时间】:2022-01-17 09:17:26
【问题描述】:

以下代码类似于我的真实应用程序。我有一个高度依赖int值s的类定义,当调用具有两个不同s值的两个类的实例时,我需要编写两次函数调用,我们有没有更简单的方法,比如using rightInst = std::conditional_t<use10, instA, instB>;我们在实例化之前使用的。


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);

【问题讨论】:

  • rightInst{}(1, 2, 3); 将调用(默认构造函数和)operator() 采用 3 ints,rightInst(1, 2, 3) 将只调用(不存在的)构造函数采用 3 ints。

标签: c++ class templates


【解决方案1】:

您可以将所选实例存储在std::variant 中,并使用std::visit 调用您的方法。您仍然需要某种条件(这里我使用三元)来存储正确的实例,因此对于这种特定情况,这似乎不是很干净。

#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

【讨论】:

    【解决方案2】:

    这里可以选择多态,因为没有什么可以阻止模板类具有多态基并覆盖继承的虚拟;

    例如

    #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);
    }
    

    决定调用哪个重载的所有逻辑都在实例化对象的过程中解决。

    使用unique_ptr 是为了简化清理(完成后销毁对象)。

    根据您的描述,我不会使用运算符函数 - 一个适当命名的虚函数(由 object-&gt;virtualFun(1,2,3) 调用)就足够了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 2019-04-15
      相关资源
      最近更新 更多