我有一个容器类,我们称之为
template <class T> CVector { ... }
当T是指针类型时,我想对这个类做一些不同的事情。类似的东西:
template <class T*> CVector< SomeWrapperClass<T> >;
其中SomeWrapperClass期望指向的东西的类型作为其参数。不幸的是,这种语法并不常用,而且经过一些挖掘,我还没有找到一种很好的方法来获得这样的工作。
为什么这样?我想在一个非常大的应用程序中更改我们的一些容器如何工作,当他们专门的类型是指针而非指针 - 理想情况下,我想这样做而不改变〜1,000个地方在代码中有CVector<Object*>
vs CVector<int>
之类的东西或其他类似东西 - 并且玩部分特化的游戏似乎是要走的路。
我在这里破解?
答案 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");
}