【问题标题】:Do function templates have a lower priority than functions of the same resolved type?函数模板的优先级是否低于相同解析类型的函数?
【发布时间】:2021-09-10 17:00:57
【问题描述】:

这与my previous question 密切相关,但我认为它足够不同,值得再发一篇。

这是我所引用的歧义的一种相当纯粹的形式:

template<typename T>
class Class {
public:
    Class() = default;

    template<typename U>
    Class(Class<U> &) {}
};

这个类有两个值得注意的潜在冲突构造函数:隐式复制构造函数和重新绑定构造函数模板。举个例子:

Class<int> foo{};
Class<int> bar{foo};

在这种情况下,重新绑定构造函数模板的解析类型将是 Class&lt;int&gt;(Class&lt;int&gt; &amp;) - 与隐式复制构造函数相同的签名!

C++ 标准是指定哪个构造函数优先,还是由实现定义?

作为附录,特殊成员函数(如复制构造函数)在这些场景中是否受到特殊处理?即,场景会

template<typename T>
class Vector {
public:
    T x, y;

    Vector foo(Vector &other) {
        ...
    }

    template<typename U>
    Vector foo(Vector<U> &other) {
        ...
    }
};

...

Vector<int> vec1{1, 2};
Vector<int> vec2{3, 4};
auto fooVec = vec1.foo(vec2);

表现与第一个示例不同?

【问题讨论】:

标签: c++


【解决方案1】:

当你有一个模板特化和一个正则函数时,如果其他一切都相等(相同的签名),正则函数被认为比特化更好。 [over.match.best.general]/2

对此进行了介绍

鉴于这些定义,如果对于所有参数 i,ICS i (F 1 ) 不是比 ICS i (F 2 ) 更差的转换序列,则可行函数 F 1 被定义为比另一个可行函数 F 2 更好的函数,然后

  • [...]
  • F1 不是函数模板特化,F2 是函数模板特化,或者,如果不是,

这意味着在您的第一种情况下,将不会使用默认编译器生成的复制构造函数。原因是默认的签名是Class(Class&lt;int&gt; const &amp;),而模板会专门化为Class(Class&lt;int&gt;&amp;)。既然不需要做 const 限定,那就更好匹配了。

您的第二个示例将使用非模板版本,因为两个调用都将解析为 Vector&lt;int&gt; foo(Vector&lt;int&gt; &amp;) ,并且由于它们匹配,因此使用非模板版本。

【讨论】:

  • 编译器生成的副本 c'tor 接受 const 限定引用。我相信第一个示例不会使用它。
  • @StoryTeller-UnslanderMonica 好地方。答案已更新。
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 2021-08-15
  • 2017-10-31
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
  • 1970-01-01
  • 2017-05-21
相关资源
最近更新 更多