如何编写一个模板,将其作为参数类,其构造函数具有互斥签名?
class A
{
A(){};
public:
int a;
A(int i) : a(i) {};
};
class B{
B(){};
public:
int a,b;
B(int i,int j) : a(i), b(j) {};
};
template <class T> class C {
public:
T* _t;
C(int i[])
{ //???
_t=new T(i[0]); //if T has T(int) signature
_t=new T(i[0],i[1]); //if T has T(int,int) signature
}
~C() {delete _t;}
};
int main()
{
int Ai[]={1,2};
C<A> _c(Ai); // template should work instantiated with A and B
C<B> _c(Ai); //
return 0;
}A和B的签名是固定的(不能更改为int[] )。上下文:我正在考虑一个包装器,它将接受一个(专门的)容器类型作为模板参数,例如T=vector<int>或T=map<int,int>,当需要调用构造函数时,问题就出现了。
发布于 2012-04-07 03:40:31
使用可变模板化的构造函数:
template <typename T> struct C
{
template <typename ...Args> C(Args &&... args)
: _t(new T(std::forward<Args>(args)...))
{
}
// ... destructor? Rule of five? Don't use pointers!!!
private:
T * _t; // ouch!
};用法:
C<A> x(1);
C<B> y(2, 3);(真正的程序员当然更喜欢成员std::unique_ptr<T> _t;,它的语义没有改变,但允许您忽略所有注释。)
发布于 2012-05-28 09:46:04
我相信Kerrek SB的答案是部分正确的,但不完整。它的失败在于C<T>的构造函数过于泛型。也就是说,如果你只看它的构造函数声明,C<T>将从任何东西构造。直到你选择了构造函数并实例化,你才会发现不是这样。到那时已经太晚了。
具体示例:
假设C<T>有:
friend bool operator<(const C&, const C&);现在,您想让C<T>成为map中的密钥
std::map<C<A>, int> m;
// ...
m.erase(m.begin());这是一个错误,因为现在有两个erase重载,如下所示:
iterator erase(const_iterator position);
size_type erase(const key_type& k);而m.begin()是一个iterator。这个iterator将同样容易地转换为const_iterator和key_type (也就是C<A>)。
现在可以通过调用以下命令来修复此问题:
m.erase(m.cbegin());而不是。但这只是过度泛型构造函数导致的问题的冰山一角。例如,分支到以下位置的代码:
std::is_constructible<C<A>, any type and any number of them>::value可能会得到误报,因为上面的代码将始终返回 true。
修复方法有点混乱,但非常实用:
template<typename T>
struct C
{
template <class ...Args,
class = typename std::enable_if
<
std::is_constructible<T, Args...>::value
>::type
>
C(Args&& ...args)
: _t(new T(std::forward<Args>(args)...))
{
}
// ...
};也就是说,向构造函数添加一个约束,这样如果它不能工作,它就不会被实例化。这是混乱的,丑陋的,不管怎样。也许你想用一个宏来修饰它。很好。但它使这个类可以工作,否则就是我上面提到的例子中的(以及许多其他问题,这些问题在几年的时间里往往会作为bug报告一次一个地出现)。
除了Kerrek SB关于在原始指针上使用unique_ptr<T>的好建议之外,我还想补充一下:
explicit的,至少在实际用例表明它确实需要存储T而不是指向T的(可能是智能的)指针之前是这样的。除非您实际尝试指向基类以实现运行时polymorphism.,否则不需要指针语义
总之:要提防过于泛型的代码,以及过于泛型的构造函数。
https://stackoverflow.com/questions/10048369
复制相似问题