10

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

template <class T> CVector { ... } 

当 T 是指针类型时,我想对这个类做一些不同的事情,例如:

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

SomeWrapperClass 期望指向事物的类型作为其参数。不幸的是,这种语法不太适用,并且经过一些挖掘,我还没有找到一种让这样的东西工作的好方法。

为什么要这样做?我想在一个非常大的应用程序中改变我们的一些容器在它们专门处理的类型是指针而不是指针时的工作方式 - 理想情况下,我想在不改变约 1,000 个位置的情况下做到这一点在代码中有类似CVector<Object*>vs之CVector<int>类的东西 - 玩部分专业化的游戏似乎是要走的路。

我在这里破解吗?

4

6 回答 6

8

如果我对您的理解正确,这可能会满足您的要求:

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>

于 2009-07-15T22:17:39.180 回答
6

这在 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();
}
于 2009-07-15T22:32:22.957 回答
4

我不认为你可以使用你描述的语法来专门化一个类......我不知道这怎么可能工作。您可以做的是专门针对指针类并使用围绕原始指针的包装类重新实现其内容。我不确定它是否会有所帮助,但本文描述了专门的指针模板。

于 2009-07-15T21:54:46.777 回答
1

Boost 类型特征库可以帮助您实现这一目标。查看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(); 
}
于 2009-07-15T22:34:52.327 回答
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");
}
于 2013-01-22T14:13:53.357 回答
0

我不认为模板那么灵活。

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

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

于 2009-07-15T21:55:33.297 回答