关于一段带有模板、转换运算符和复制构造函数的代码的问题
Questions about a piece of code with templates, conversion operator and copy ctor
关于下面这段代码的两个问题:
template <class T> class A {
protected:
T j;
public:
A(T k) :j(k) {cout << *this;}
~A() { cout << *this; }
A(const A<T> &a) {
j = a.j;
cout << *this;
}
virtual void print() const {cout << j << ' ';}
friend ostream &operator << (ostream &os, const A<T> &a) {
a.print();
return os;
}
operator T() { return j;}
};
template <class T> class inherit:public A<T> {
T field;
public:
inherit(const T&t) :A<T>(t), field(1+t) {
cout << *this;
}
void print() const {
A<T>::print();
cout << field << ' ';
}
};
int main(){
inherit <int> b(3);
inherit <string> c("asdf");
string k="str";
c + k;//error no operator +
b + 5;//no error
}
为什么inherit <int> b(3);
会导致inherit
的copy ctor?为什么要复制而不是使用默认 ctor 从头开始创建 inherit
的新实例?
为什么 b+5;
会导致转换运算符 operator T()
而为什么 c+k
不会发生?
- Why does
inherit <int> b(3);
leads to the copy ctor of inherit? Why copy instead of making a new instance of inherit from scratch using the default ctor?
首先,它不会导致复制构造函数,实例实际上是从头开始。
没有使用默认构造函数,因为您没有调用默认构造函数。默认构造函数将使用空参数列表调用(除了,在这种情况下,您还必须省略括号以避免令人烦恼的解析):
inherit <int> b; // this would call the default constructor
如果您将参数传递给构造函数,则会调用非默认构造函数。 inherit <int> b(3);
导致调用 inherit(const T&)
,在此模板实例中为 inherit(const int&)
。它不是 inherit
.
的复制构造函数
- Why does b+5; leads to the casting operator operator T()
因为没有operator+(const inherit<int>&, int)
也没有定义类似的成员函数。因此,重载决策寻找可以隐式转换操作数的替代方案。碰巧的是,存在一个内置的 operator+(int, int)
,并且 inherit<int>
可以隐式转换为 A<int>
(因为它是一个基数)并且 A<int>
可以转换为一个int
(因为铸造运算符)。因此,该运算符最终被调用。
and why it doesn't happen with c+k?
首先,您甚至无法实例化 inherit <string>
,因为构造函数试图将一个 int 添加到参数字符串中,该字符串没有有效的重载。
现在,假设构造函数已修复,因此 inherit<string>
可以存在,c + k
似乎仍然不起作用。我怀疑这是因为该字符串需要比 int
更多的转换,因为它不是原始字符串,并且您已经达到了用户定义的转换序列可以具有的最大深度。您可以显式地将 inherit<string>
转换为 string
以缩短转换序列:
static_cast<std::string>(c) + k; // this works
- Why does b+5; leads to the conversion operator operator T() and why it doesn't happen with c+k?
编译器抱怨一段完全不同的代码。如果删除 main()
中的 +,您会看到它仍然抱怨 operator+
:
http://melpon.org/wandbox/permlink/H3cUUaf8fSnbYDwA
原因在这一行:
inherit(const T&t) :A<T>(t), field(1+t) {
你有 1 + t
,其中 t
是 std::string
。 std::string
没有 int
的运算符 +,因此无法编译。
关于下面这段代码的两个问题:
template <class T> class A {
protected:
T j;
public:
A(T k) :j(k) {cout << *this;}
~A() { cout << *this; }
A(const A<T> &a) {
j = a.j;
cout << *this;
}
virtual void print() const {cout << j << ' ';}
friend ostream &operator << (ostream &os, const A<T> &a) {
a.print();
return os;
}
operator T() { return j;}
};
template <class T> class inherit:public A<T> {
T field;
public:
inherit(const T&t) :A<T>(t), field(1+t) {
cout << *this;
}
void print() const {
A<T>::print();
cout << field << ' ';
}
};
int main(){
inherit <int> b(3);
inherit <string> c("asdf");
string k="str";
c + k;//error no operator +
b + 5;//no error
}
为什么
inherit <int> b(3);
会导致inherit
的copy ctor?为什么要复制而不是使用默认 ctor 从头开始创建inherit
的新实例?为什么
b+5;
会导致转换运算符operator T()
而为什么c+k
不会发生?
- Why does
inherit <int> b(3);
leads to the copy ctor of inherit? Why copy instead of making a new instance of inherit from scratch using the default ctor?
首先,它不会导致复制构造函数,实例实际上是从头开始。
没有使用默认构造函数,因为您没有调用默认构造函数。默认构造函数将使用空参数列表调用(除了,在这种情况下,您还必须省略括号以避免令人烦恼的解析):
inherit <int> b; // this would call the default constructor
如果您将参数传递给构造函数,则会调用非默认构造函数。 inherit <int> b(3);
导致调用 inherit(const T&)
,在此模板实例中为 inherit(const int&)
。它不是 inherit
.
- Why does b+5; leads to the casting operator operator T()
因为没有operator+(const inherit<int>&, int)
也没有定义类似的成员函数。因此,重载决策寻找可以隐式转换操作数的替代方案。碰巧的是,存在一个内置的 operator+(int, int)
,并且 inherit<int>
可以隐式转换为 A<int>
(因为它是一个基数)并且 A<int>
可以转换为一个int
(因为铸造运算符)。因此,该运算符最终被调用。
and why it doesn't happen with c+k?
首先,您甚至无法实例化 inherit <string>
,因为构造函数试图将一个 int 添加到参数字符串中,该字符串没有有效的重载。
现在,假设构造函数已修复,因此 inherit<string>
可以存在,c + k
似乎仍然不起作用。我怀疑这是因为该字符串需要比 int
更多的转换,因为它不是原始字符串,并且您已经达到了用户定义的转换序列可以具有的最大深度。您可以显式地将 inherit<string>
转换为 string
以缩短转换序列:
static_cast<std::string>(c) + k; // this works
- Why does b+5; leads to the conversion operator operator T() and why it doesn't happen with c+k?
编译器抱怨一段完全不同的代码。如果删除 main()
中的 +,您会看到它仍然抱怨 operator+
:
http://melpon.org/wandbox/permlink/H3cUUaf8fSnbYDwA
原因在这一行:
inherit(const T&t) :A<T>(t), field(1+t) {
你有 1 + t
,其中 t
是 std::string
。 std::string
没有 int
的运算符 +,因此无法编译。