C++模板和歧义问题
我有一个指针类的子集,如下所示:
template <typename T>
struct Pointer
{
Pointer();
Pointer(T *const x);
Pointer(const Pointer &x);
template <typename t>
Pointer(const Pointer<t> &x);
operator T *() const;
};
最后一个构造函数的目标是允许传递子类的指针,或者基本上任何可隐式转换为 T * 的类型。这个实际的规则仅由构造函数的定义强制执行,编译器实际上无法仅通过声明来弄清楚它。如果我删除它,并尝试将 Pointer
传递给 Pointer
的构造函数,我会收到编译错误,尽管可能存在通过 <代码>运算符 T *()。
它在解决上述问题的同时,也带来了另一个问题。如果我有一个重载函数,其中一个重载采用 Pointer
,另一个重载采用 Pointer
,并且我尝试使用 Pointer
调用它;SubClass>
,我在两个重载之间存在歧义,当然,其目的是调用后一个重载。
有什么建议吗? (希望我说得足够清楚)
I have a subset of a pointer class that look like:
template <typename T>
struct Pointer
{
Pointer();
Pointer(T *const x);
Pointer(const Pointer &x);
template <typename t>
Pointer(const Pointer<t> &x);
operator T *() const;
};
The goal of the last constructor is to allow to pass a Pointer
of a subclass, or basically any type that is implicitly convertable to T *
. This actual rule is only enforced by the definition of the constructor and the compiler can't actually figure it out by the declaration alone. If I drop it, and try to pass a Pointer<Sub>
to a constructor of Pointer<Base>
, I get a compile error, despite of the possible path through operator T *()
.
While it solves the above problem, it creates another one. If I have an overloaded function whose one overload takes a Pointer<UnrelatedClass>
and the other takes Pointer<BaseClass>
, and I try to invoke it with a Pointer<SubClass>
, I get an ambiguity between the two overloads, with the intention, ofcourse, that the latter overload will be called.
Any suggestions? (Hopefully I was clear enough)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决您的问题的方法称为 SFINAE(替换失败不是错误)
如果 U* 可转换为 T*,则
enable_if
将有一个 typedef 成员type
默认为 void。然后,一切都很好。如果 U* 不可转换为 T*,则缺少此 typedef 成员,替换将失败并且构造函数模板将被忽略。这解决了您的转换和歧义问题。
回应评论:
is_convertible
看起来像这样:The cure for your problem is called SFINAE (substitution failure is not an error)
If U* is convertible to T* the
enable_if
will have a typedef membertype
defaulting to void. Then, everything is fine. If U* is not convertible to T* this typedef member is missing, substitution fails and the constructor template is ignored.This solves your conversion and ambiguity problems.
In response to the comment:
is_convertible
looks something like this:尝试使有问题的构造函数明确,例如:
和/或删除
operator T *() const;
- 我认为这也会产生歧义。编辑
检查std::auto_ptr接口,并与您的进行比较。至少他们解决了歧义。
Try to make the constructor in question explicit, e.g.:
And/or remove the
operator T *() const;
- I think this one will also create an ambiguity.EDIT
Check the std::auto_ptr interface, and compare with yours. At least they solved the ambiguity.