可以返回不同模板类型的C ++方法

时间:2015-03-30 16:02:30

标签: c++ templates

所以我有2个类,一个名为Node<T>的模板化类和一个名为Context的非模板类。我在Context中有一些方法需要返回任何类型的Node<T>

例如,有时它需要返回Node<double>,有时还需要Node<int>等。我也有一些我想要的方法可以采用任何类型的Node<T>作为参数。

我有什么方法可以做到这一点,不包括Context中针对每种可能情况的单独方法?

class Node
{
  T Val;
public:
  Node(T value) : Val(val) {}
  T getVal() { return Val; } 
}

class Context
{
  Node<type>* divide(Node<type>* LHS, Node<type>* RHS)
  {
    type Solution LHS->getVal() / RHS->getVal();
    return new Node<type>(Solution);
  }
}

例如,在这里,如果答案最终为小数,我想返回Node<double>,否则我想返回Node<int>。它会返回Node<double>,解决方案为Node->Val;。有时,操作会返回Node<int>(如4/2),因此会返回Node<int>代替。这是我想要做的一个减少的例子,但它有同样的想法。

1 个答案:

答案 0 :(得分:1)

如果您需要不同的返回类型,则无法在C ++中实现虚拟方法的多态性。除非您使用boost::any之类的内容或返回不透明的void *

对于C ++的工作方式,如果你需要不同的返回类型,你需要不同的签名,因此需要2种不同的方法,但是C ++有一些语法糖,让编译器处理它(模板),这样编码器只需要编写1个方法一次

template < typename T>
class Node{
    //...
};

class Container{


public:

    template< typename T>
    Node< T> * getNode(){

    }
};

可能的实施:

#include <stack>
#include <string>
#include <typeinfo>

class Container{
    std::stack<void *> data;
    std::stack<std::string> names;
public:


    //push a node on the stack (you have to allocate it)
    template< typename T>
    void addNode( Node< T> * p){
        data.push(static_cast<void*>(p));
        names.push(typeid(T).name());
    }


    template< typename T>
    Node< T>* removeNode(){
        if(names.top()==typeid(T).name()){
            names.pop();
            Node< T>* node = reinterpret_cast<Node<T>*>(data.top());
            data.pop();
            return node;
        }
        return NULL; //returns nullptr;
    }
};

当然,这只是一个工作示例(假设您已在某处定义了Node)。为了向您展示一种可能的方式(字面上这是我能想到的最简单的例子,但您可以提高性能并使用它来设计解决问题的方法)。

用法示例:

Container c;
Node<double> n1* = new Node<double>(5.0);
Node<double> n2* = new Node<double>(3.0);
Node<int>    n3* = new Node<int>(100);
c.addNode(n1);
c.addNode(n2);
c.addNode(n3); 
//since I used a stack now I check node in reversed order
cout<<     c.getNode<double>() == n3  <<endl; // false! n3 use "int"
cout<<     c.getNode<int>() == n3 <<endl; //true! 
cout<<     c.getNode<double>() == n2 <<endl; //true! 
cout<<     c.getNode<int>() == n1 <<endl; //false! n1 use double
cout<<     c.getNode<double>() == n1 <<endl; //true

delete n1;
delete n2;
delete n3;