指针作为模板参数?

时间:2009-07-15 21:46:01

标签: c++ templates partial-specialization

我有一个容器类,我们称之为

template <class T> CVector { ... } 

当T是指针类型时,我想对这个类做一些不同的事情。类似的东西:

template <class T*> CVector< SomeWrapperClass<T> >;

其中SomeWrapperClass期望指向的东西的类型作为其参数。不幸的是,这种语法并不常用,而且经过一些挖掘,我还没有找到一种很好的方法来获得这样的工作。

为什么这样?我想在一个非常大的应用程序中更改我们的一些容器如何工作,当他们专门的类型是指针而非指针 - 理想情况下,我想这样做而不改变〜1,000个地方在代码中有CVector<Object*> vs CVector<int>之类的东西或其他类似东西 - 并且玩部分特化的游戏似乎是要走的路。

我在这里破解?

6 个答案:

答案 0 :(得分:7)

如果我理解正确,这可能会做你想要的:

template<typename T>
class CVector { ... };

template<typename T>
class CVector<T*> : public CVector< SomeWrapperClass<T> > {
public:
  // for all constructors:
  CVector(...) : CVector< SomeWrapperClass<T> >(...) {
  }
};

它添加了一个额外的继承层,以将CVector<T*>变为CVector< SomeWrapperClass<T> >。如果您需要添加其他方法以确保T*的预期接口与SomeWrapperClass<T>提供的接口之间的完全兼容性,这可能也很有用。

答案 1 :(得分:5)

这在C ++中运行得很好......

#include <iostream>

template <class T>
class CVector
{
public:
    void test() { std::cout << "Not wrapped!\n"; }
};

template <class T>
class CVector<T*>
{
public:
    void test() { std::cout << "Wrapped!\n"; }
};

int main()
{
    CVector<int> i;
    CVector<double> d;
    CVector<int*> pi;
    CVector<double*> pd;
    i.test();
    d.test();
    pi.test();
    pd.test();
}

答案 2 :(得分:4)

我认为你不能使用你描述的语法来专门化一个类...我不知道它是如何工作的。你可以做的是专门用于指针的类,并使用原始指针周围的包装类重新实现它的内容。我不确定它是否会有所帮助,但this article描述了指针的专用模板。

答案 3 :(得分:1)

Boost type traits library可以帮助您实现这一目标。查看is_pointer类型特征。

#include <boost/type_traits.hpp>
#include <iostream>
#include <vector>

using namespace std;

template <class T>
class CVector {
  public:
    void addValue(const T& t) {
      values_.push_back(t);
    }

    void print() {
      typedef boost::integral_constant<bool,
        ::boost::is_pointer<T>::value> truth_type;

      for (unsigned int i = 0; i < values_.size(); i++) 
        doPrint(values_[i], truth_type());
    }


  private:
    void doPrint(const T& t, const boost::false_type&) {
      cout << "Not pointer. Value:" << t << endl;
    }

    void doPrint(const T& t, const boost::true_type&) {
      cout << "Pointer. Value: " << *t << endl;
    }

    std::vector<T> values_;
 };


int main() {
  CVector<int> integers;
  integers.addValue(3);
  integers.addValue(5);
  integers.print();

  CVector<int*> pointers;
  int three = 3;
  int five = 5;
  pointers.addValue(&three);
  pointers.addValue(&five);
  pointers.print(); 
}

答案 4 :(得分:0)

我不认为模板非常灵活。

一种非常强力的方法是专门针对所有指针类型......这就克服了使用模板的问题。

你能有一个不同的CVector类,只用于指针向量吗?

答案 5 :(得分:0)

我同意rlbond的回答。我已根据您的需要对其进行了一些修改。 CVector可以是CVector本身的派生类。然后,您可以使用不同的成员和功能。

#include <iostream>
#include <string>
template <class T>
class CVector
{
public:
    void test() { std::cout << "Not wrapped!\n"; }
    void testParent() { std::cout << "Parent Called\n";}
};

template <class T>
class CVector<T*>:
    public CVector<T>
{
public:
    void test(std::string msg) { std::cout << msg; testParent(); }
};

int main()
{
    CVector<int> i;
    CVector<double> d;
    CVector<int*> pi;
    CVector<double*> pd;
    i.test();
    d.test();
    pi.test("Hello\n");
    pd.test("World\n");
    system("pause");
}