【发布时间】:2019-08-09 22:11:52
【问题描述】:
按照下面的代码-sn-p,我尝试通过Boo<T>::Boo(Foo const &) 构造函数重载传递Boo<int> 实例,但我无法做到。
#include <iostream>
struct Foo { };
template <typename T>
struct Boo : public Foo
{
// Boo(Boo<T> const &) = delete; // Leaves (2) without a constructor
Boo() { std::cout << "Beep " << sizeof(T) << std::endl; }
Boo(Foo const &) { std::cout << "Boop " << sizeof(T) << std::endl; }
};
void fun(Foo const &) { }
int main()
{
Boo<int> x; // (1) Output: Beep 4
Boo<int> y(x); // (2) Output:
Boo<double> z(x); // (3) Output: Boop 8
fun(x); // (4) Compiles
return 0;
}
在 code-sn-p 中,我尝试编写一个简单的场景,如果需要,可以复制粘贴来玩弄。
- 在 (1) 处,我们生成一个
Boo<int>实例x,它使用Boo<T>::Boo()构造函数重载。 - 在(2)处,我们将实例
x传递给实例y的构造函数,它使用隐式定义的复制构造函数Boo<T>::Boo(Boo<T> const &)。因此,我们不会收到输出消息。 - 在(3)处,我们将实例
x传递给实例z的构造函数,它使用Boo<T>::Boo(Foo const &)构造函数重载。 - 在 (4) 处,我们确认
Boo<int>可以被编译器隐式转换为Foo const &并传递给fun(Foo const &)函数。
问题:我怎样才能让 (2) 通过与 (3) 相同的构造函数,为什么它还没有这样做?
如果有人能看到我错过的内容,我将不胜感激,如果有人指出我的话。
【问题讨论】:
-
有什么问题?
-
为什么要让 2 和 3 做同样的事情?隐式复制构造函数在 2 中是完全匹配的,因此它将是首选。
-
@ÖöTiib 谢谢你,这肯定会在未来。 @1201ProgramAlarm 感谢您的修复。 @NathanOliver 我同意你的看法,尽管在我的情况下,无论
T如何,我都希望所有Boo<T>都通过与(3)相同的构造函数。你提到这是一个“完全匹配”,我不能否认,但这也是为什么我添加了注释代码行,deletes 是隐式定义的构造函数,以强制 (2) 表现为 (3 ),但 (2) 不能匹配任何可用的构造函数。不过,fun函数可以证明它确实匹配。 -
所以,你应该依赖静态多态性(这里,基于模板)而不是运行时多态性(参考你写的)。为什么不?
template<typename T, typename = std::enable_if<std::is_assignable<typename Foo>, T>::value> Boo(T const &)然后继续你的代码 -
@user9335240 感谢您的评论。我认为您的建议是一个可能的解决方案,具体取决于所需的方法。随意将其作为替代解决方案发布在答案部分。我个人试图确定是否有一种方法可以有效地使用运行时多态性来实现这一目标。
标签: c++ inheritance constructor overloading