4

我的情况如下:

Class Bar {
...
}

template <class T>
class Foo {
public:
  ...
  Foo(Foo<Bar> bar) {
    ...
  }
  ...
}

因此,类 Foo 的构造函数之一可以采用由 Bar 参数化的类 Foo 的元素。这一切都很好,直到我实例化由 Bar 参数化的类 Foo ,其中这个构造函数被解释为不是我想要的复制构造函数。我想知道如何在不干扰复制构造函数的情况下让构造函数获取这样的元素。例如我可以这样做:

template <class T>
class Foo {
public:
  ...
  Foo(Foo<Bar> bar, int unused) {
    ...
  }
  ...
}

它工作正常,因为现在构造函数与复制构造函数不冲突。有没有标准的方法来处理这个问题?

4

2 回答 2

3

如果您的类模板不需要声明复制构造函数(在一般情况下),则可以将构造函数声明为

Foo(Foo<Bar> const& bar);

这通常是一个转换构造函数和一个复制构造函数Foo<Bar>。其他特化将在适用的情况下使用隐式声明的复制构造函数。

否则,将构造函数设为模板可确保它不是特殊成员。话虽如此,必须注意该构造函数不要干扰复制构造函数。这不好,但你可以这样做:

template<typename U>
Foo(U bar, typename boost::enable_if<boost::is_same<U, Foo<Bar> > >::type* = 0);

这是一个不是复制构造函数的构造函数,并且只会在传递 type 的参数时使用Foo<Bar>。请注意,由于重载决议的规则,复制构造函数Foo<Bar>将优先于此构造函数。


前面是针对 C++03 的。这是一个简单的 C++11 解决方案:

template<int = 0>
Foo(Foo<Bar>);
于 2012-10-03T18:40:14.110 回答
0

这实际上不是一个有效的复制构造函数,因为复制构造函数应该遵循以下四种格式之一:

MyClass( const MyClass& other );
MyClass( MyClass& other );
MyClass( volatile const MyClass& other );
MyClass( volatile MyClass& other );

为了让一切按预期工作,将您的参数作为指针传递:

Foo(Foo<Bar>* bar) {
    // Logic
}

如果你通过值传递它,如果你的逻辑模仿一个复制构造函数,你可以很好地创建一个无限循环。

于 2012-10-03T18:27:02.083 回答