How to get an instance of a class template from an if statement? (C ++)

Suppose I have a class template that has a member pData, which is an array of AxBan arbitrary type T.

template <class T> class X{ 
public:
    int A;
    int B;
    T** pData;
    X(int a,int b);
    ~X();        
    void print(); //function which prints pData to screen

};  
template<class T>X<T>::X(int a, int b){ //constructor
    A = a;
    B = b;
    pData = new T*[A];
    for(int i=0;i<A;i++)
        pData[i]= new T[B];
    //Fill pData with something of type T
}
int main(){
    //...
    std::cout<<"Give the primitive type of the array"<<std::endl;
    std::cin>>type;
    if(type=="int"){
        X<int> XArray(a,b);
    } else if(type=="char"){
        X<char> Xarray(a,b);
    } else {
        std::cout<<"Not a valid primitive type!";
    } // can be many more if statements.
    Xarray.print() //this doesn't work, as Xarray is out of scope.
}

Since the Xarray instance is built inside the if statement, I cannot use it anywhere. I tried to make a pointer before the if statements, but since the type of the pointer at this point is unknown, I did not succeed.

What would be the right way to deal with such a problem?

+5
source share
4 answers

++ - , , . , , .

, , . ++, . :

struct IPrintable {
   virtual void print() = 0;
};

template<class T>
class X : public IPrintable {
  // Same code as you showed above.
};

int main() {
  std::cout<<"Give the primitive type of the array"<<std::endl;
  std::cin>>type;

  std::unique_ptr<IPrintable> XArray;

  if(type=="int"){
      XArray.reset(new X<int>(a,b));
  } else if(type=="char"){
      XArray.reset(new X<char>(a,b));
  } else {
      std::cout<<"Not a valid primitive type!";
  } // can be many more if statements.

  Xarray->print() // this works now!
}

XArray. - , .

+1

, X<int> x<char> .

, , .

, , .

, , X<> templated , print() ( , ). , , : , - . , , , .

std::function<void ()> , , , "" ( : X<int>, x<char> , , print()).

- , X<int>, x<char> (boost:: variant < > ). , print() .

, :

typedef boost::variant<X<int>, X<char>> genericX;

class print_visitor : public boost::static_visitor<void>
{
public:
    template <typename SomeType>
    void operator()(const SomeType& x) const
    {
        // Your print implementation
        // x is your underlying instance, either X<char> or X<int>.
        // You may also make several non-templated overloads of
        // this operator if you want to provide different implementations.
    }
};

int main()
{
  boost::optional<genericX> my_x;

  if (type=="int") {
    my_x = X<int>(a,b);
  } else if(type=="char") {
    my_x = X<char>(a,b);
  }

  // This calls the appropriate print.
  if (my_x) {
    boost::apply_visitor(print_visitor(), *my_x)
  }
}

, : "", , , . " ", .

+4

, , . X<int> X<char> .

, ( ). , X<T> , Printable, unique_ptr<Printable>:

unique_ptr<Printable> r;
if(type=="int"){
    r.reset(new X<int>(a,b));
} else if(type=="char"){        
    r.reset(new X<char>(a,b);
}
r->print();

, , .

, , if, if. , . , , , :

template<class T>
void workWithType(int a, int b)
{
   X<T> Xarray(a, b);
   Xarray.print();
}

//...

if(type=="int"){
    workWithType<int>(a,b);
} else if(type=="char"){
    workWithType<char>(a,b);
} 
+1

, main, , ... main (, ) , :

template <typename T>
void generateAndPrint(int a, int b) {
   X<T> x(a,b);
   x.print();
}
int main() { ...
   if (type=="int") generateAndPrint<int>(a,b);
   else if (type=="char") generateAndPrint<char>(a,b);
   else ...
}
+1

All Articles