- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在尝试为 shared_ptr
编写一个包装器时,它会在支持继承类的同时向用户隐藏内存的分配和释放,我偶然发现了非常奇怪的错误,表明编译器在一个过程中查找了错误的函数重载,或者我关于混合重载和模板的知识是错误的。所以我写了这个东西来测试:
#include <iostream>
void out(int i) {
std::cout << i << '\n';
}
template <class T>
struct Inst {
template <class TT>
Inst(const TT &) {out(1);}
Inst(const Inst &) {out(2);}
template <class TT>
Inst(TT &&) {out(3);}
Inst(Inst &&) {out(4);}
Inst() {out(-1);}
~Inst() {out(1000);}
};
class K {};
class KK : K {};
int main() {
out(3000);
K k; KK kk; Inst<K> i;
Inst<K> I1{k};
Inst<K> I2{kk};
Inst<K> I3{i};
Inst<K> I4{K()};
Inst<K> I5{KK()};
Inst<K> I6{Inst<K>()};
out(2000);
}
我合理期望的是 I1
和 I2
写 1
,I3
写 2
,I4
和I5
写3
和I6
写4
,并且至少有两个其他对象在不同的位置写入 -1
。但是,当使用 -std=c++11
使用 gcc 4.8.2 进行编译时,我的机器跳过了一个对象,并为调用的所有其他非自动构造函数编写了 3
.我做错了什么?
最佳答案
Inst(TT &&) {out(3);}
中的 TT&&
有点特殊。所以,特别的是,甚至还有一个专门为它们创造的“术语”,称为 universal reference
。
简而言之,TT&&
不是您认为的那样。这里有两件事起作用:引用折叠和模板推导
由于 TT
是一个模板参数,并且您将 &&
放在它前面,这就是 T&&
在您的示例中的样子:
Inst<K> I1{k}; ---> Inst(K&)
Inst<K> I2{kk}; ---> Inst(KK&)
Inst<K> I3{i}; ---> Inst(Inst<K>&)
Inst<K> I4{K()}; ---> Inst(K&&)
Inst<K> I5{KK()} ---> Inst(KK&&)
TT&&
变成了一个完全匹配,并且是您进行的所有调用的选定构造函数,这就是您看到 3
的原因对于每一个(i
和 I6
除外)。
如需进一步阅读,请参阅:
关于C++ 模板特化 : unexpected function overload lookup result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21391603/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!