我问的最后一个问题是我在试图理解另一件事时偶然发现的……我也无法理解(不是我的一天)。
这是一个很长的问题陈述,但至少我希望这个问题可能对很多人有用,而不仅仅是我。
我的代码如下:
template <typename T> class V;
template <typename T> class S;
template <typename T>
class V
{
public:
T x;
explicit V(const T & _x)
:x(_x){}
V(const S<T> & s)
:x(s.x){}
};
template <typename T>
class S
{
public:
T &x;
explicit S(V<T> & v)
:x(v.x)
{}
};
template <typename T>
V<T> operator+(const V<T> & a, const V<T> & b)
{
return V<T>(a.x + b.x);
}
int main()
{
V<float> a(1);
V<float> b(2);
S<float> c( b );
b = a + V<float>(c); // 1 -- compiles
b = a + c; // 2 -- fails
b = c; // 3 -- compiles
return 0;
}
表达式 1 和 3 完美运行,而表达式 2 无法编译。
如果我理解正确,会发生什么:
表达式 1
- c is
const
通过使用标准转换序列(仅包含一个限定转换)隐式转换为。 V<float>(const S<T> & s)
被调用并且const V<float>
对象生成的时间(我们称之为t)。它已经是 const 限定的,因为它是一个时间值。- a转换为 const 类似于c。
operator+(const V<float> & a, const V<float> & b)
被调用,导致const V<float>
我们可以称之为q的时间类型。V<float>::operator=(const & V<float>)
调用默认值。
我到这里还好吗?如果我犯了最细微的错误,请告诉我,因为我试图尽可能深入地了解隐式转换......
表达式 3
- c转换为
V<float>
. 为此,我们有一个用户定义的转换序列:
1.1。第一个标准转换:S<float>
通过const S<float>
资格转换。
1.2. 用户定义的转换:const S<float>
通过构造函数V<float>
。 1.3 二级标准转换:通过资格转换。V<float>(const S<T> & s)
V<float>
const V<float>
V<float>::operator=(const & V<float>)
调用默认值。
表达式 2?
我不明白的是为什么第二个表达式有问题。为什么以下顺序是不可能的?
- c转换为
V<float>
. 为此,我们有一个用户定义的转换序列:
1.1。初始标准转换:S<float>
到const S<float>
通过资格转换。
1.2. 用户定义的转换:const S<float>
通过构造函数V<float>
。 1.3. 最终标准转换:通过资格转换。V<float>(const S<T> & s)
V<float>
const V<float>
- 步骤 2 到 6 与表达式 1 的情况相同。
在阅读了 C++ 标准之后,我:'嘿!也许问题与 13.3.3.1.2.3 有关!其中指出:
如果自定义转换由模板转换函数指定,则第二个标准转换序列必须具有精确匹配秩。
但事实并非如此,因为资格转换具有完全匹配的排名......
我真的一点头绪都没有...
好吧,不管你有没有答案,谢谢你阅读到这里:)