有关一段带有模板、转换运算符和复制 ctor 的代码的问题
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
的复制?为什么要复制而不是使用默认 ctor 从头开始创建inherit
的新实例?为什么
b+5;
会导致转换运算符operator T()
,为什么c+k
不会发生这种情况?
- 为什么
inherit <int> b(3);
会导致继承的复制?为什么要复制而不是使用默认 ctor 从头开始创建继承的新实例?
首先,它不会导致复制构造函数,并且实例实际上是从头开始创建的。
未使用默认构造函数,因为您没有调用默认构造函数。默认构造函数将使用空参数列表调用(除了,在这种情况下,您还必须省略括号以避免烦人的解析(:
inherit <int> b; // this would call the default constructor
如果将参数传递给构造函数,则将调用非默认构造函数。 inherit <int> b(3);
会导致调用inherit(const T&)
在此模板实例中inherit(const int&)
。它不是inherit
的复制构造函数。
- 为什么 b+5; 会导致转换运算符运算符 T((
因为没有定义operator+(const inherit<int>&, int)
也没有类似的成员函数。因此,重载解析会查找可将操作数隐式转换为的替代项。碰巧的是,存在内置operator+(int, int)
,并且inherit<int>
可以隐式转换为A<int>
(因为它是基数(,A<int>
可以转换为int
(因为它是转换运算符(。因此,该操作员最终被调用。
为什么 C+K 不会发生这种情况?
首先,您甚至无法实例化inherit <string>
因为构造函数尝试向参数字符串添加 int,该字符串没有有效的重载。
现在,假设构造函数是固定的,以便inherit<string>
可以存在,c + k
似乎仍然不起作用。我怀疑这是因为字符串需要比int
更多的转换,因为它不是基元,并且您已经达到了用户定义的转换序列可以具有的最大深度。您可以将inherit<string>
显式转换为string
以缩短转换顺序:
static_cast<std::string>(c) + k; // this works
- 为什么 b+5; 会导致转换运算符运算符 T((,为什么 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
,所以这不会编译。
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 构造函数和转换运算符之间的重载解析
- 分配给转换运算符失败-C++
- 转换运算符不适用于sleep_until
- 尝试使用算术运算符阻止隐式转换
- 错误 C2679:二进制"<<":未找到采用类型 'std::string_view' 的右侧操作数的运算符(或者没有可接受的转换)
- 是否可以将带有字符串化运算符的宏转换为 constexpr?
- C2678 二进制 '==':未找到采用 'Card' 类型左操作数的运算符(或者没有可接受的转换)
- 继承模板化转换运算符
- 将 OR 逻辑运算符从 C++ 转换为 Fortran
- 模板转换运算符在 clang 6 和 clang 7 之间的区别
- 如何在C++中正确重载运算符转换字符*?
- 将私有结构哈希器运算符转换为静态
- 混合类型的Boost运算符-转换和私有成员
- 如何将 c++ 运算符转换为 Java
- 运算符转换,GCC 和 clang:哪个编译器是正确的
- 将 istream 运算符>>转换为 istream getline
- 在C++中,将任意在位运算符转换为一元运算符
- 将运算符转换为 std::复杂<double>
- 为什么按位否定运算符"~"转换为 int?(从"int"转换为"无符号字符"可能会改变其值)