请考虑以下类层次结构:
template <typename T>
struct base {
base() = default;
base(const base<T>& other) {
std::cout << "base copy c'tor\n";
}
};
template <typename T, std::size_t size>
struct derived : base<T> {
derived() = default;
derived(const derived<T, size>& other)
: base<T>{other} {
std::cout << "derived copy c'tor\n";
}
};
以及以下derived
类的对象的创建:
int main() {
derived<int, 10> d{};
derived<int, 10> copy{d};
}
此程序的输出如预期的那样:
基本副本管理员
派生副本
但是,我希望derived
的副本构造函数可以与任何derived<T, other_size>
的值一起使用,而无论其size
的值如何(尽管T
必须匹配),所以我将实现更改为以下内容:
template <typename T>
struct base {
base() = default;
base(const base<T>& other) {
std::cout << "base copy c'tor\n";
}
};
template <typename T, std::size_t size>
struct derived : base<T> {
derived() = default;
template <std::size_t size2> // now a template with *size2*
derived(const derived<T, size2>& other)
: base<T>{other} {
std::cout << "derived copy c'tor\n";
}
};
经过如下测试:
int main() {
derived<int, 10> d{};
derived<int, 5> copy{d};
}
它再次产生正确的输出:
基本副本管理员
派生副本
一切正常,除了size
值 match 的情况外。再次考虑以下情况:
int main() {
derived<int, 10> d{};
derived<int, 10> copy{d};
}
使用template
derived
复制构造函数,仅调用基本版本,从而导致输出:
基本副本管理员
我不想要这种行为。即使derived
值匹配,如何强制使用size
复制构造函数?为什么在这种情况下首选base
的副本构造函数?